Swift中的通用委托

时间:2015-07-04 10:22:54

标签: ios swift generics delegates

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

我有以下代表:

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)

我想了几个小时,我不知道为什么它不起作用。任何人遇到这个问题?

2 个答案:

答案 0 :(得分:1)

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

的工作方式是:

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)
    }
}

...但在后一个代码段Bike不是类型而是占位符,其效果与使用T的情况相同。

答案 1 :(得分:0)

如果Swift中的普通代表不是函数,那么它们是不可能的。因为函数(闭包)可以是通用的。请参阅我的要点,我尝试解决同样的问题:https://gist.github.com/artyom-razinov/fe8c2b7611a0ba3bd2a3