我想详细了解
.drive(resultsTableView.rx_itemsWithCellIdentifier("WikipediaSearchCell",
cellType: WikipediaSearchCell.self))
{ (_, viewModel, cell) in
cell.viewModel = viewModel
}
Run Code Online (Sandbox Code Playgroud)
来自WikipediaSearchViewController.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)
Run Code Online (Sandbox Code Playgroud)
给
不能使用类型'(String,cellType:UITableViewCell.Type)'的参数列表调用'rx_itemsWithCellIdentifier'
对于driveArg1和
没有更多上下文,表达式的类型是模糊的
对于driveArg2.
的签名drive和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 {}
Run Code Online (Sandbox Code Playgroud)
但在这一点上,Swift语法对我来说是难以理解的.任何人都可以解释签名和代码中发生的事情吗?
在这里,由于缺乏上下文, Swift 编译器无法推断出driveArg1和 的类型。driveArg2当在调用中内联使用时drive(),编译器有更多关于每个参数的类型的线索,并且我们最终不需要为这些类型进行注释。
考虑到这一点,让我们尝试为这两个变量添加类型注释。
首先,我们将更新 swift 2.2 的签名rx_itemsWithCellIdentifier,删除令人困惑的柯里化语法并添加通用注释
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, S.Generator.Element, Cell) -> Void)
-> Disposable
Run Code Online (Sandbox Code Playgroud)
driveArg2curriedArgument这是我们传递给of 的参数,并且将是我们在应用之后drive()传递给的参数。因此,需要匹配rx_itemsWithCellIdentifier(source: O)(Int, S.Generator.Element, Cell) -> Void
该类型定义中有两个未知的S.Generator.Element和Cell。它们是通用的,所以我们需要弄清楚它们是什么。
Cell很简单,这里就是我们要配置的cell的类型WikipediaSearchCell。S.Generator.Element有点难,但我们可以很容易地弄清楚。我们从中得到O.E == S序列的类型是我们在源元素的尖括号之间找到的类型。在我们的例子中,source( temp1)的类型是Observable<[SearchResultViewModel]>。SoS的类型是[SearchResultViewModel]then, S.Generator.Elementwill 是SearchResultViewModel好的,我们现在有了签名driverArg2:
(Int, SearchResultViewModel, WikipediaSearchCell) -> Void
Run Code Online (Sandbox Code Playgroud)
为了简化接下来的事情,让我们typealias为它定义一个
typealias CellConfigurator = (Int, SearchResultViewModel, WikipediaSearchCell) -> Void
Run Code Online (Sandbox Code Playgroud)
我们现在可以定义driveArg2
let driveArg2: CellConfigurator = { (_, viewModel: SearchResultViewModel, cell: WikipediaSearchCell) in
cell.viewModel = viewModel
}
Run Code Online (Sandbox Code Playgroud)
driveArg1现在这driveArg2已经不成问题了,弄清楚类型driveArg1变得更容易了。它只是 的返回类型rx_itemsWithCellIdentifier,替换了通用部分
typealias DriveArg2Type = (source: Observable<[SearchResultViewModel]>) -> (CellConfiguration) -> Disposable
Run Code Online (Sandbox Code Playgroud)
drive签名随着这一切的扩展,类型签名drive有望变得更有意义:
drive(Self -> R1 -> R2, curriedArgument: R1) -> R2
// where
Self = Observable<[SearchResultViewModel]>
R1 = CellConfigurator
R2 = Disposable
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2480 次 |
| 最近记录: |