Что делает следующий пример кода из RxSwift/RxCocoa?
Я пытаюсь понять в деталях
.drive(resultsTableView.rx_itemsWithCellIdentifier("WikipediaSearchCell",
cellType: WikipediaSearchCell.self))
{ (_, viewModel, cell) in
cell.viewModel = viewModel
}
из WikipediaSearchViewController.стремительные линии 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)
дает
не удается вызвать 'rx_itemsWithCellIdentifier' со списком аргументов типа '(String, cellType: UITableViewCell.Type)'
для driveArg1 и
тип выражения неоднозначно без дополнительного контекста
для driveArg2.
подписи drive
и rx_itemsWithCellIdentifier
are
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 для меня совершенно непонятен. Может ли кто-нибудь объяснить подписи и что происходит в коде?
1 ответов
здесь компилятор Swift не может вывести тип driveArg1
и driveArg2
из-за отсутствия контекста. При использовании inline в drive()
вызов, компилятор имеет больше подсказок о том, каким может быть тип каждого параметра, и нам в конечном итоге не нужно аннотировать для этих типов.
учитывая это, давайте попробуем добавить аннотацию типа для этих двух переменных.
во-первых, мы обновим подпись rx_itemsWithCellIdentifier
С swift 2.2 в виду, удаление путаницы 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
это аргумент, который мы передаем curriedArgument
of drive()
, и будет аргумент, который мы переходим к rx_itemsWithCellIdentifier
после применения (source: O)
. Таким образом, он должен соответствовать (Int, S.Generator.Element, Cell) -> Void
в этом определении типа есть два неизвестных,S.Generator.Element
и Cell
. Они являются общими, поэтому нам нужно выяснить, что они такое.
-
Cell
легко, это тип ячейку мы хотим настроить, здесьWikipediaSearchCell
. -
S.Generator.Element
это немного сложнее, но мы можем понять это довольно легко. Мы получаем отO.E == S
что тип последовательности-это тип, который мы находим между угловой скобкой нашего исходного элемента. В нашем случае source (temp1
) имеет типObservable<[SearchResultViewModel]>
. Так что ы[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
, С заменой общей части
typealias DriveArg2Type = (source: Observable<[SearchResultViewModel]>) -> (CellConfiguration) -> Disposable
drive
подпись
со всем этим расширен, подпись типа для drive
надеюсь, что имеет больше смысла:
drive(Self -> R1 -> R2, curriedArgument: R1) -> R2
// where
Self = Observable<[SearchResultViewModel]>
R1 = CellConfigurator
R2 = Disposable