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