.drive(resultsTableView.rx_itemsWithCellIdentifier("WikipediaSearchCell",cellType: WikipediaSearchCell.self)) { (_,viewmodel,cell) in cell.viewmodel = viewmodel }
来自维基百科SearchViewController.swift第47-64行.
我试图提取参数来查看具体的类型签名,但是重写
let temp1 = searchBar.rx_text .asDriver() .throttle(0.3) .distinctUntilChanged() .flatMapLatest { query in API.getSearchResults(query) .retry(3) .retryOnBecomesReachable([],reachabilityService: ReachabilityService.sharedReachabilityService) .startWith([]) // clears results on new search term .asDriver(onErrorJustReturn: []) } .map { results in results.map(SearchResultviewmodel.init) } let driveArg1 = resultsTableView.rx_itemsWithCellIdentifier("WikipediaSearchCell",cellType: WikipediaSearchCell.self) let driveArg2 = { (_,viewmodel: SearchResultviewmodel,cell: WikipediaSearchCell) in cell.viewmodel = viewmodel } temp1.drive(driveArg1,curriedArgument: driveArg2) .addDisposableTo(disposeBag)
给
cannot invoke ‘rx_itemsWithCellIdentifier’ with an argument list of type ‘(String,cellType: UITableViewCell.Type)’
对于driveArg1和
type of expression is ambiguous without more context
对于driveArg2.
驱动器和rx_itemsWithCellIdentifier的签名是
public func drive<R1,R2>(with: Self -> R1 -> R2,curriedArgument: R1) -> R2 {} public func rx_itemsWithCellIdentifier(cellIdentifier: String,cellType: Cell.Type = Cell.self)(source: O)(configureCell: (Int,S.Generator.Element,Cell) -> Void) -> Disposable {}
但在这一点上,Swift语法对我来说是不可理解的.任何人都可以解释签名,代码中会发生什么?
考虑到这一点,我们尝试为这两个变量添加类型注释.
首先,我们将使用swift 2.2更新rx_itemsWithCellIdentifier的签名,从而消除令人困惑的currying语法,并添加通用注释
public func rx_itemsWithCellIdentifier <S: SequenceType,Cell: UITableViewCell,O : ObservableType where O.E == S> (cellIdentifier: String,cellType: Cell.Type = Cell.self) -> (source: O) -> (configureCell: (Int,Cell) -> Void) -> Disposable
driveArg2的类型
这是我们传递给curriedArgument的驱动()的参数,并且将是在应用(source:O)之后传递给rx_itemsWithCellIdentifier的参数.因此,它需要匹配(Int,Cell) – >空虚
这种类型定义中有两个未知的,S.Generator.Element和Cell.它们是通用的,所以我们需要弄清楚它们是什么.
> Cell很容易,它是我们要配置的单元格的类型,这里是WikipediaSearchCell.
> S.Generator.Element有点困难,但我们可以很容易地弄清楚.我们从O.E == S得到,序列的类型是我们在源元素的尖括号之间找到的类型.在我们的例子中,source(temp1)的类型为Observable< [SearchResultviewmodel]>.所以S的类型是[SearchResultviewmodel],因此S.Generator.Element将是SearchResultviewmodel
好,我们现在有driverArg2的签名:
(Int,SearchResultviewmodel,WikipediaSearchCell) -> Void
为了简化接下来的内容,我们为它定义一个typealias
typealias CellConfigurator = (Int,WikipediaSearchCell) -> Void
我们现在可以定义driveArg2
let driveArg2: CellConfigurator = { (_,cell: WikipediaSearchCell) in cell.viewmodel = viewmodel }
driveArg1的类型
现在,driveArg2已经失败了,找出driveArg1的类型变得更加容易.它只是rx_itemsWithCellIdentifier的返回类型,替换了通用部分
typealias DriveArg2Type = (source: Observable<[SearchResultviewmodel]>) -> (CellConfiguration) -> Disposable
驱动签名
随着所有这一切的扩大,驱动器的类型签名希望更有意义:
drive(Self -> R1 -> R2,curriedArgument: R1) -> R2 // where Self = Observable<[SearchResultviewmodel]> R1 = CellConfigurator R2 = Disposable