LoginSignup
80

More than 5 years have passed since last update.

RxSwift: UITableViewCellのreuse対策

Posted at

reuseableなUITableViewで何も考えずにcellのイベントをRxSwift,RxCocoaで取ろうとすると、cell一つひとつが再利用されるたびにRxSwiftのオブジェクトが積み重なっていきます。そのため再利用の際に適切に破棄する必要があります。

Cell側

MyCell.swift
import UIKit

class MyCell: UITableViewCell {    
    var disposeBag = DisposeBag()
    let button = UIButton()
.
.
.
    override func prepareForReuse() {
        super.prepareForReuse()
        // 再利用時にdisposeBagに溜まっていたものを破棄
        self.disposeBag = DisposeBag()
    }
}

Table側

MyTableView.swift
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as! MyCell
        cell.button.rx_tap
            .subscribeNext {
                // handle tap event
            }
            // cell側のdisposeBagへ追加
            .addDisposableTo(cell.disposeBag)
        return cell
    }

確認方法

3秒ごとにRxSwift関連の総オブジェクト数をログに出します。
上記対策をしない場合、Tableのスクロールによってオブジェクト数が増えていくのが分かります。

MyAppDelegate.swift

let timer = NSTimer.init(timeInterval: 3.0, target: NSBlockOperation.init(block: {
    print("Resource count \(RxSwift.resourceCount)")
}), selector: #selector(NSOperation.main), userInfo: nil, repeats: true)
NSRunLoop.mainRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes)

参考

ReactiveX/RxSwift Invoked multiple times in UITableViewCell #437

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
80