繁体   English   中英

访问另一个类中的视图控制器方法 [Swift]

[英]Accessing view controller methods inside another class [Swift]

我通过在我的 ViewController (AnimalsVC) 中创建一个UITableViewDiffableDataSource类,将UITableViewDiffableDataSource用于我的 tableview 的数据源。 每当我尝试从我的数据源类中获取我的 ViewController 的数据数组(或任何其他变量/函数)时,我都会收到此错误:

Instance member 'animalsArray' of type 'AnimalsVC' cannot be used on an instance of nested type 'AnimalsVC.DataSource'

我不确定为什么会收到此错误,因为我的 DataSource 类在我的 ViewController 类中。 这是我的代码:

class AnimalsVC: UIViewController {
   var animalsArray = []

   class DataSource: UITableViewDiffableDataSource<Int, Animal> {
      override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {

         let items = animalsArray //<- This is where the error occurs   
         
         return true
      }
   }

}

我不确定为什么会出现此错误,因为我的 DataSource 类在我的 ViewController 类中。

那没什么区别。 在另一个类中声明一个类只是命名内部类,即它现在称为AnimalsVC.DataSource 它不会导致内部类的一个实例能够神奇地看到外部类的实例内部(实际上我们完全不清楚我们将谈论哪些实例)。 您嵌套的类声明是无用的,因此您最好不要这样做。

相反,如果 DataSource 需要查看 AnimalsVC 内部,请执行您通常会做的事情:为您的 DataSource 实例提供AnimalsVC 实例的引用

class AnimalsVC: UIViewController {
    var animalsArray = // ...
}

class DataSource: UITableViewDiffableDataSource<Int, Animal> {
    weak var vc : AnimalsVC?
    // ...
}

创建 DataSource 实例时,将其vc设置为self 现在 DataSource 可以查询 AnimalsVC 实例的实例属性。

(实际上,我在自己的代码中所做的是给我的 UITableViewDiffableDataSource 子类一个自定义的指定初始值设定项。这样,我就可以创建数据源并将其传递给视图控制器的一个引用,所有这些都一举完成。)

为了从内部访问外部类,您需要将引用传递给它。 它不是自动的,例如 Java。

假设 Animal 对象是在别处定义的,那么你可以做的是:

class AnimalsVC: UIViewController {
   var animalsArray = [] as [Animal]

   class DataSource: UITableViewDiffableDataSource<Int, Animal> {

      var myanimal:AnimalsVC

      init(animal: AnimalsVC){
          myanimal = animal
          super.init()
      }

      override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {

         let items = myanimal.animalsArray //<- This should not be an error any more   

         return true
      }
   }

}

数据应包含在 DataSource 类中。 将您的动物数组移动到 DataSource 类中。

如果您需要从任何地方轻松访问它,请在 DataSource 下将其声明为:

static var animalsArray = [Animal]()

然后您可以使用 DataSource.animalsArray 从任何地方访问它,例如:

DataSource.animalsArray.append(animal)

我想您可以将其创建为 AnimalsVC 下的静态变量,但实际上应该在数据源中声明数据。

这将使您的类看起来像这样:

class AnimalsVC: UIViewController {
   class DataSource: UITableViewDiffableDataSource<Int, Animal> {
    static var animalsArray = [Animal]()
    override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        let items = DataSource.animalsArray
        return true
      }
   }
}

这是不可能的,因为。

“NestedTypes”无法访问其他类甚至容器类中的实例成员或函数,这与“继承”不同,您可以访问父类的实例成员或函数。

如果您希望您的实施工作没有错误。 “静态”会帮助你。

struct Animal {
  var label: String
}

class AnimalVC {
  static var animals: [Animal] = []
  var dataSource = DataSource()

  class DataSource {
    func add(_ animal: Animal) {
      animals.append(animal)
    }
    func display() {
      print(animals.map { $0.label })
    }
    func remove(_ index: Int) -> String? {
      guard index < (animals.count - 1) else { return nil }
      return animals.remove(at: index).label
    }
  }

  func load() {
    dataSource.display()
    dataSource.add(Animal(label: "Dog"))
    dataSource.display()
    for i in ["Cat", "Fish", "Bird"] {
      dataSource.add(Animal(label: i))
    }
    dataSource.display()
    print(vc.dataSource.remove(AnimalVC.animals.count) ?? "Cannot delete.")
  }
}

测试。

let vc = AnimalVC()
vc.load()

嵌套类型

方便地定义实用程序类和结构,纯粹是为了在更复杂的类型引用的上下文中使用

遗产

继承现有类的特性

来源

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM