11

詳しく理解しようとしている

.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)

与える

タイプ '(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 {}

しかし、現時点では、Swift の構文はまったく理解できません。署名とコードで何が起こるかを説明できる人はいますか?

4

1 に答える 1

4

ここで、コンテキストがないため、Swift コンパイラはdriveArg1andの型を推測できません。driveArg2呼び出し内でインラインで使用するdrive()と、コンパイラは各パラメーターの型が何であるかについてより多くの手がかりを得ることができ、最終的にそれらの型に注釈を付ける必要がなくなります。

これを考慮して、これら 2 つの変数に型注釈を追加してみましょう。

まず、rx_itemsWithCellIdentifierswift 2.2 を念頭に置いて の署名を更新し、混乱を招くカリー化構文を削除し、一般的な注釈も追加します。

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

これはcurriedArgumentofに渡す引数であり、適用後drive()に渡す引数になります。したがって、一致する必要がありますrx_itemsWithCellIdentifier(source: O)(Int, S.Generator.Element, Cell) -> Void

この型定義には不明な 2S.Generator.ElementつとCell. それらは一般的なものであるため、それらが何であるかを理解する必要があります。

  • Cell簡単です。設定したいセルのタイプですWikipediaSearchCell
  • S.Generator.Element少し難しいですが、かなり簡単に理解できます。シーケンスのO.E == S型は、ソース要素の山かっこの間にある型であることがわかります。この場合、 source( temp1) は typeObservable<[SearchResultViewModel]>です。SoSの型は、[SearchResultViewModel]したがって、S.Generator.ElementSearchResultViewModel

よし、これで の署名が得られた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、ジェネリック部分が置き換えられています

typealias DriveArg2Type = (source: Observable<[SearchResultViewModel]>) -> (CellConfiguration) -> Disposable

driveサイン

これをすべて展開すると、 の型シグネチャdriveがより意味のあるものになることを願っています。

drive(Self -> R1 -> R2, curriedArgument: R1) -> R2
// where
Self = Observable<[SearchResultViewModel]>
R1 = CellConfigurator
R2 = Disposable
于 2016-03-11T13:13:36.430 に答える