RxSwift/RxCocoa 中的以下示例代码有什么作用?
What does the following example code from RxSwift/RxCocoa do?
我正在尝试详细了解
.drive(resultsTableView.rx_itemsWithCellIdentifier("WikipediaSearchCell",
cellType: WikipediaSearchCell.self))
{ (_, viewModel, cell) in
cell.viewModel = viewModel
}
来自 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)
给予
cannot invoke 'rx_itemsWithCellIdentifier' with an argument list of type '(String, cellType: UITableViewCell.Type)'
对于 driveArg1 和
type of expression is ambiguous without more context
对于 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 {}
但在这一点上 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
类型 driveArg2
这是我们传递给 drive()
的 curriedArgument
的参数,在应用 (source: O)
之后将是我们传递给 rx_itemsWithCellIdentifier
的参数。因此,它需要匹配 (Int, S.Generator.Element, Cell) -> Void
这个类型定义中有两个未知数,S.Generator.Element
和Cell
。它们是通用的,所以我们需要弄清楚它们是什么。
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, SearchResultViewModel, WikipediaSearchCell) -> Void
我们现在可以定义driveArg2
let driveArg2: CellConfigurator = { (_, viewModel: SearchResultViewModel, cell: WikipediaSearchCell) in
cell.viewModel = viewModel
}
类型driveArg1
现在 driveArg2
已经不存在了,弄清楚 driveArg1
的类型变得更容易了。它只是 rx_itemsWithCellIdentifier
的 return 类型,替换了通用部分
typealias DriveArg2Type = (source: Observable<[SearchResultViewModel]>) -> (CellConfiguration) -> Disposable
drive
签名
随着所有这些扩展,drive
的类型签名有望更有意义:
drive(Self -> R1 -> R2, curriedArgument: R1) -> R2
// where
Self = Observable<[SearchResultViewModel]>
R1 = CellConfigurator
R2 = Disposable
我正在尝试详细了解
.drive(resultsTableView.rx_itemsWithCellIdentifier("WikipediaSearchCell",
cellType: WikipediaSearchCell.self))
{ (_, viewModel, cell) in
cell.viewModel = viewModel
}
来自 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)
给予
cannot invoke 'rx_itemsWithCellIdentifier' with an argument list of type '(String, cellType: UITableViewCell.Type)'
对于 driveArg1 和
type of expression is ambiguous without more context
对于 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 {}
但在这一点上 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
类型 driveArg2
这是我们传递给 drive()
的 curriedArgument
的参数,在应用 (source: O)
之后将是我们传递给 rx_itemsWithCellIdentifier
的参数。因此,它需要匹配 (Int, S.Generator.Element, Cell) -> Void
这个类型定义中有两个未知数,S.Generator.Element
和Cell
。它们是通用的,所以我们需要弄清楚它们是什么。
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, SearchResultViewModel, WikipediaSearchCell) -> Void
我们现在可以定义driveArg2
let driveArg2: CellConfigurator = { (_, viewModel: SearchResultViewModel, cell: WikipediaSearchCell) in
cell.viewModel = viewModel
}
类型driveArg1
现在 driveArg2
已经不存在了,弄清楚 driveArg1
的类型变得更容易了。它只是 rx_itemsWithCellIdentifier
的 return 类型,替换了通用部分
typealias DriveArg2Type = (source: Observable<[SearchResultViewModel]>) -> (CellConfiguration) -> Disposable
drive
签名
随着所有这些扩展,drive
的类型签名有望更有意义:
drive(Self -> R1 -> R2, curriedArgument: R1) -> R2
// where
Self = Observable<[SearchResultViewModel]>
R1 = CellConfigurator
R2 = Disposable