【问题标题】:Generic delegate in SwiftSwift 中的通用委托
【发布时间】:2015-07-04 10:22:54
【问题描述】:

我正在编写一个有助于自动获取分页数据的小类。

我有以下代表:

protocol DataAPIDelegate: class {
  func fetchItemsForPage<T>(api: DataAPI<T>, page: Int, onFinish: ([T] -> ())
}

还有存储委托的DataAPI类:

class DataAPI<T> {
  weak var delegate: DataAPIDelegate? = nil

  //...
  //some other methods
}

然后,我要做的是编写一个使用 DataAPI 并通过 DataAPIDelegate 与该对象通信的视图控制器:

class CarsViewController: DataAPIDelegate {
  var dataAPI = DataAPI<Car>

  // MARK :- DataAPIDelegate
  func fetchItemsForPage<T>(api: DataAPI<T>, page: Int, onFinish: ([T] -> ()) {
    let cars: [Car] = //some method for getting cars
    onFinish(cars)
  }
}

我得到了错误:Cannot invoke 'onFinish' with an argument list of type '([Car])' 在行中:onFinish(cars)

我考虑了几个小时,但我不知道为什么它不起作用。有人遇到过这个问题吗?

【问题讨论】:

  • 在您的CarsViewController 中将T 替换为Car 以修复编译错误。查看this 关于通用页面生成器的博文,...
  • Car 替换T 后,我得到了错误:'Car' is not identical to 'Car' 与获取汽车:let car: [Car] = ... 一致。似乎 Swift 编译器将 Car 视为类型变量(因为 fetchItemsForPage&lt;Car&gt; 声明)和类型本身(因为分配给 cars 变量的数组),所以它无法匹配它。

标签: ios swift generics delegates


【解决方案1】:

通用函数为T 引用的多种类型提供单一模板实现,而您似乎正在尝试做的是专门为Car 类型提供fetchItemsForPage 方法的实现。

的工作方式是:

protocol DataAPIDelegate: class {
    func fetchItemsForPage<T>(api: DataAPI<T>, page: Int, onFinish: ([T] -> ()))
}

class DataAPI<T> {
    weak var delegate: DataAPIDelegate? = nil

    //...
    //some other methods
}

struct Car { }

class CarsViewController: DataAPIDelegate {
    var dataAPI = DataAPI<Car>()

    // MARK :- DataAPIDelegate
    func fetchItemsForPage<T>(api: DataAPI<T>, page: Int, onFinish: ([T] -> ())) {
        let items: [T] = [T]()
        onFinish(items)
    }
}

...而您正在尝试做的是:

struct Bike { }

class BikesViewController: DataAPIDelegate {
    var dataAPI = DataAPI<Bike>()

    // MARK :- DataAPIDelegate
    func fetchItemsForPage<Bike>(api: DataAPI<Bike>, page: Int, onFinish: ([Bike] -> ())) {
        let items: [Bike] = [Bike]()
        onFinish(items)
    }
}

...但在后者中,sn-p Bike 不是类型而是占位符,其工作方式与使用 T 相同。

【讨论】:

  • 谢谢,我现在明白这个问题了。那么在这种情况下我能做些什么呢? CarsViewController 如何与DataAPI 通信?
  • 我不确定您到底想达到什么目的。你能详细说明一下吗?
  • 嗨 Anton Bronnikov,快速提问,如果我不能实例化一个对象,我该如何设置委托 = self,因为它是一个我无法在其他类中访问的泛型类,但我希望泛型类调用另一个类中的函数,因此需要委托?
【解决方案2】:

通用委托在 Swift 中是不可能的,如果它们不仅仅是函数的话。因为函数(闭包)可以是通用的。请参阅我试图解决相同问题的要点:https://gist.github.com/artyom-razinov/fe8c2b7611a0ba3bd2a3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多