简体   繁体   English

RxSwift / RxCocoa的以下示例代码有什么作用?

[英]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 driverx_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编译器无法推断driveArg1driveArg2的类型。 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

Type of 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.ElementCell 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]> . 在我们的例子中,source( 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
}

Type of 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM