3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【RxSwift】クロージャが二重になる場合の [weak self] について

Posted at

結論

クロージャが二重になる場合、どちらのクロージャでも self を弱参照でキャプチャする必要がある

環境

  • Xcode 12.5.1(12E507)
  • RxSwift 5.1.3
  • RxDataSources 4.0.1

事例

  • UICollectionViewCellProvider 内部で購読処理を行う

アンチパターン

self.dataSource = UICollectionViewDiffableDataSource<PseudoSection, PseudoItem>(collectionView: collectionView, cellProvider: { (collectionView: UICollectionView, indexPath: IndexPath, item: PseudoItem) -> UICollectionViewCell? in {
    
    if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PseudoCellIdentifier", for: indexPath) {

        cell.someSignal
            .emit(onNext: { [weak self] _ in
                 
                 self?.someRelay.accept(())
            })
            .disposed(by: cell.disposeBag)
         
        return cell
    }
    
    return nil
}
  • 一見 self を弱参照しているためメモリリークは発生しないように見える
  • 実際にはメモリリークが発生する
  • [weak self] でキャプチャされる selfCellProvider クロージャ内で強参照扱いになっている?

修正

self.dataSource = UICollectionViewDiffableDataSource<PseudoSection, PseudoItem>(collectionView: collectionView, cellProvider: { [weak self](collectionView: UICollectionView, indexPath: IndexPath, item: PseudoItem) -> UICollectionViewCell? in {
    
    if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PseudoCellIdentifier", for: indexPath) {

        cell.someSignal
            .emit(onNext: { [weak self] _ in
                 
                 self?.someRelay.accept(())
            })
            .disposed(by: cell.disposeBag)
         
        return cell
    }
    
    return nil
}
  • CellProvider クロージャの内部で self を弱参照でキャプチャするように
  • 特段 guard などでオプショナルを外さなくてもこのままでOK
3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?