RxSwift - 绑定到 tableView 的可选问题
RxSwift - optional issue on binding to tableView
我有一个 UITableView
和一个 users
变量,其签名如下:
let users: Variable<[User]?> = Variable<[User]?>(nil)
当我尝试在 UITableView 中绑定这个用户数组时,出现了错误 Generic parameter 'Self' could not be inferred
。这仅在我观察 Optional 类型时发生。为什么会这样?这种情况的解决方法是什么?
这是我的做法的一个例子:
private func bind() {
// Does not compile: Generic parameter 'Self' could not be inferred
users.asObservable().bind(to:
tableView.rx.items(cellIdentifier: "UserCell",
cellType: UITableViewCell.self)) { (index, user, cell) in
// Cell setup.
}.disposed(by: disposeBag)
}
您看到此错误是因为编译器无法推断传递给以下函数的 Optional
变量 users
的类型,这些函数适用于泛型并且需要能够推断类型。
Swift中的一个Optional
实际实现如下图。我想如果 Optional
可能是 nil
又名 .none
编译器无法推断方法的类型,例如items
和 bind(to:)
适用于泛型。
public enum Optional<Wrapped> : ExpressibleByNilLiteral {
/// The absence of a value.
///
/// In code, the absence of a value is typically written using the `nil`
/// literal rather than the explicit `.none` enumeration case.
case none
/// The presence of a value, stored as `Wrapped`.
case some(Wrapped)
/// Creates an instance that stores the given value.
public init(_ some: Wrapped)
//...
}
解决方法 1.):您可以使用 filterNil()
(RxOptionals
库)来避免该问题。
private func bind() {
users.asObservable().filterNil().bind(to:
tableView.rx.items(cellIdentifier: "UserCell",
cellType: UITableViewCell.self)) { (index, user, cell) in
// Cell setup.
}.disposed(by: disposeBag)
}
解决方法 2.):使 users
non-optional。如果您没有用户,只需设置一个空数组作为值。
let users: Variable<[User]> = Variable<[User]>([])
解决方法 3.):在 map
函数中使用 Nil-Coalescing Operator ??
,如
private func bind() {
users.asObservable().map { optionalUsers -> [User] in
return optionalUsers ?? []
}
.bind(to:
tableView.rx.items(cellIdentifier: "UserCell",
cellType: UITableViewCell.self)) { (index, user, cell) in
// Cell setup.
}.disposed(by: disposeBag)
}
旁注:Variable
在最新版本的 RxSwift
中已弃用
仅供参考:
实施items
public func items<S: Sequence, Cell: UITableViewCell, O : ObservableType>
(cellIdentifier: String, cellType: Cell.Type = Cell.self)
-> (_ source: O)
-> (_ configureCell: @escaping (Int, S.Iterator.Element, Cell) -> Void)
-> Disposable
where O.E == S {
return { source in
return { configureCell in
let dataSource = RxTableViewReactiveArrayDataSourceSequenceWrapper<S> { (tv, i, item) in
let indexPath = IndexPath(item: i, section: 0)
let cell = tv.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! Cell
configureCell(i, item, cell)
return cell
}
return self.items(dataSource: dataSource)(source)
}
}
}
实施bind(to:)
public func bind<O: ObserverType>(to observer: O) -> Disposable where O.E == E {
return self.subscribe(observer)
}
我在没有可选类型的情况下遇到了同样的错误。发生这种情况是因为我在 UITableView
.
中使用了 UICollectionViewCell
子类
我有一个 UITableView
和一个 users
变量,其签名如下:
let users: Variable<[User]?> = Variable<[User]?>(nil)
当我尝试在 UITableView 中绑定这个用户数组时,出现了错误 Generic parameter 'Self' could not be inferred
。这仅在我观察 Optional 类型时发生。为什么会这样?这种情况的解决方法是什么?
这是我的做法的一个例子:
private func bind() {
// Does not compile: Generic parameter 'Self' could not be inferred
users.asObservable().bind(to:
tableView.rx.items(cellIdentifier: "UserCell",
cellType: UITableViewCell.self)) { (index, user, cell) in
// Cell setup.
}.disposed(by: disposeBag)
}
您看到此错误是因为编译器无法推断传递给以下函数的 Optional
变量 users
的类型,这些函数适用于泛型并且需要能够推断类型。
Swift中的一个Optional
实际实现如下图。我想如果 Optional
可能是 nil
又名 .none
编译器无法推断方法的类型,例如items
和 bind(to:)
适用于泛型。
public enum Optional<Wrapped> : ExpressibleByNilLiteral {
/// The absence of a value.
///
/// In code, the absence of a value is typically written using the `nil`
/// literal rather than the explicit `.none` enumeration case.
case none
/// The presence of a value, stored as `Wrapped`.
case some(Wrapped)
/// Creates an instance that stores the given value.
public init(_ some: Wrapped)
//...
}
解决方法 1.):您可以使用 filterNil()
(RxOptionals
库)来避免该问题。
private func bind() {
users.asObservable().filterNil().bind(to:
tableView.rx.items(cellIdentifier: "UserCell",
cellType: UITableViewCell.self)) { (index, user, cell) in
// Cell setup.
}.disposed(by: disposeBag)
}
解决方法 2.):使 users
non-optional。如果您没有用户,只需设置一个空数组作为值。
let users: Variable<[User]> = Variable<[User]>([])
解决方法 3.):在 map
函数中使用 Nil-Coalescing Operator ??
,如
private func bind() {
users.asObservable().map { optionalUsers -> [User] in
return optionalUsers ?? []
}
.bind(to:
tableView.rx.items(cellIdentifier: "UserCell",
cellType: UITableViewCell.self)) { (index, user, cell) in
// Cell setup.
}.disposed(by: disposeBag)
}
旁注:Variable
在最新版本的 RxSwift
仅供参考:
实施items
public func items<S: Sequence, Cell: UITableViewCell, O : ObservableType>
(cellIdentifier: String, cellType: Cell.Type = Cell.self)
-> (_ source: O)
-> (_ configureCell: @escaping (Int, S.Iterator.Element, Cell) -> Void)
-> Disposable
where O.E == S {
return { source in
return { configureCell in
let dataSource = RxTableViewReactiveArrayDataSourceSequenceWrapper<S> { (tv, i, item) in
let indexPath = IndexPath(item: i, section: 0)
let cell = tv.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! Cell
configureCell(i, item, cell)
return cell
}
return self.items(dataSource: dataSource)(source)
}
}
}
实施bind(to:)
public func bind<O: ObserverType>(to observer: O) -> Disposable where O.E == E {
return self.subscribe(observer)
}
我在没有可选类型的情况下遇到了同样的错误。发生这种情况是因为我在 UITableView
.
UICollectionViewCell
子类