[英]What does the following example code from RxSwift/RxCocoa do?
I'm trying to understand in detail 我想详细了解
.drive(resultsTableView.rx_itemsWithCellIdentifier("WikipediaSearchCell",
cellType: WikipediaSearchCell.self))
{ (_, viewModel, cell) in
cell.viewModel = viewModel
}
from WikipediaSearchViewController.swift lines 47-64. 来自WikipediaSearchViewController.swift第47-64行。 I've tried to extract the arguments to look at the concrete type signatures, but a rewrite to
我试图提取参数来查看具体的类型签名,但重写为
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)
gives 给
cannot invoke 'rx_itemsWithCellIdentifier' with an argument list of type '(String, cellType: UITableViewCell.Type)'
不能使用类型'(String,cellType:UITableViewCell.Type)'的参数列表调用'rx_itemsWithCellIdentifier'
for driveArg1 and 对于driveArg1和
type of expression is ambiguous without more context
没有更多上下文,表达式的类型是模糊的
for driveArg2. 对于driveArg2。
The signatures of drive
and rx_itemsWithCellIdentifier
are 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 {}
but at this point Swift syntax is darn incomprehensible for me. 但在这一点上,Swift语法对我来说是难以理解的。 Can anyone explain the signatures and what happens in the code?
任何人都可以解释签名和代码中发生的事情吗?
Here, Swift compiler cannot infer the type of driveArg1
and driveArg2
because of a lack of context. 这里,由于缺少上下文,Swift编译器无法推断
driveArg1
和driveArg2
的类型。 When used inline within the drive()
call, the compiler have more clues as of what the type of each parameter can be, and we end-up not needing to annotate for those types. 当在
drive()
调用中内联使用时,编译器有更多线索,因为每个参数的类型可以是什么,并且我们最终不需要为这些类型添加注释。
Taking this into account, lets try to add type annotation for those two variables. 考虑到这一点,让我们尝试为这两个变量添加类型注释。
First, we'll update the signature of rx_itemsWithCellIdentifier
with swift 2.2 in mind, removing the confusing currying syntax and also adding the generic annotations 首先,我们将使用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, S.Generator.Element, Cell) -> Void)
-> Disposable
driveArg2
driveArg2
类型 It's the argument we pass to curriedArgument
of drive()
, and will be the argument we pass to rx_itemsWithCellIdentifier
after applying (source: O)
. 这是我们传递给
curriedArgument
of drive()
的参数,并且是我们在应用之后传递给rx_itemsWithCellIdentifier
的参数(source: O)
。 Thus, it needs to match (Int, S.Generator.Element, Cell) -> Void
因此,它需要匹配
(Int, S.Generator.Element, Cell) -> Void
There are two unknown in this type definition, S.Generator.Element
and Cell
. 在这种类型定义中有两个未知的,
S.Generator.Element
和Cell
。 They are generic, so we need to figure out what they are. 它们是通用的,所以我们需要弄清楚它们是什么。
Cell
is easy, it's the type of the cell we want to configure, here WikipediaSearchCell
. Cell
很容易,它是我们想要配置的单元的类型,这里是WikipediaSearchCell
。 S.Generator.Element
is a bit harder, but we can figure it out pretty easily. S.Generator.Element
有点困难,但我们可以很容易地解决它。 We get from OE == S
that the type of the sequence is the type we find between the angle bracket of our source element. OE == S
得到序列的类型是我们在源元素的尖括号之间找到的类型。 In our case, source ( temp1
) is of type Observable<[SearchResultViewModel]>
. temp1
)的类型为Observable<[SearchResultViewModel]>
。 So S
's type is [SearchResultViewModel]
hence, S.Generator.Element
will be SearchResultViewModel
S
的类型是[SearchResultViewModel]
因此, S.Generator.Element
将是SearchResultViewModel
Good, we now have the signature of driverArg2
: 好的,我们现在有了
driverArg2
的签名:
(Int, SearchResultViewModel, WikipediaSearchCell) -> Void
To simplify what comes next, lets define a typealias
for it 为了简化接下来的内容,我们为它定义一个
typealias
typealias CellConfigurator = (Int, SearchResultViewModel, WikipediaSearchCell) -> Void
We can now define driveArg2
我们现在可以定义
driveArg2
let driveArg2: CellConfigurator = { (_, viewModel: SearchResultViewModel, cell: WikipediaSearchCell) in
cell.viewModel = viewModel
}
driveArg1
driveArg1
类型 Now that driveArg2
is out of the way, figuring out the type driveArg1
of gets easier. 现在
driveArg2
已经driveArg2
,找出类型driveArg1
变得更容易了。 It is simply the return type of rx_itemsWithCellIdentifier
, with the generic portion replaced 它只是
rx_itemsWithCellIdentifier
的返回类型,替换了泛型部分
typealias DriveArg2Type = (source: Observable<[SearchResultViewModel]>) -> (CellConfiguration) -> Disposable
drive
signature drive
签名 With all this expanded, the type signature for drive
hopefully makes more sense: 随着所有这些扩展,
drive
的类型签名希望更有意义:
drive(Self -> R1 -> R2, curriedArgument: R1) -> R2
// where
Self = Observable<[SearchResultViewModel]>
R1 = CellConfigurator
R2 = Disposable
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.