RxSwift asDriver映射和强自身

问题描述 投票:1回答:1

我正在尝试弄清是否要在此处创建保留周期。我想使用以下内容将集合视图的当前偏移量绑定到UIPageControl

collectionView
    .rx
    .contentOffset
    .asDriver()
    .map { Int($0.x) / Int(self.collectionView.frame.width) }
    .drive(pageControl.rx.currentPage)
    .disposed(by: disposeBag)

只是想知道这是否可以,或者该自我是否会创建一个保留周期?

swift rx-swift
1个回答
0
投票

是的,您的代码创建了一个保留周期,因为您的链对self进行了严格的引用,而self对链进行了强引用(通过disposeBag。)

此外,这样的代码是代码的味道,因为您依赖于map中的副作用(self.collectionView.frame.width的值随时间而变化),您不应该这样做,因为它会使您的代码不可测试。

这是一个更符合体系结构的解决方案:

class ViewController: UIViewController {

    @IBOutlet weak var collectionView: UICollectionView!
    @IBOutlet weak var pageControl: UIPageControl!

    private let collectionViewFrame = ReplaySubject<CGRect>.create(bufferSize: 1)
    private let disposeBag = DisposeBag()

    deinit {
        collectionViewFrame.onCompleted()
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        currentPage(
            offset: collectionView.rx.contentOffset.asObservable(),
            frame: collectionViewFrame.asObservable()
        )
            .bind(to: pageControl.rx.currentPage)
            .disposed(by: disposeBag)
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        collectionViewFrame.onNext(self.collectionView.frame)
    }
}

// This is your logic. Since it is separate from your view code, it can be tested/reused.
func currentPage(offset: Observable<CGPoint>, frame: Observable<CGRect>) -> Observable<Int> {
    return Observable.combineLatest(offset, frame)
        .map { Int($0.0.x) / Int($0.1.width) }
}
© www.soinside.com 2019 - 2024. All rights reserved.