防止在Swift函数指针中保留循环

时间:2015-01-25 15:20:33

标签: swift automatic-ref-counting

如何在Swift

中作为对象传递函数时阻止保留周期

想象一下,你有一个像这样的数据源对象

import UIKit
class MagicDataSource:NSObject,UITableViewDatasource {

    deinit {
        println("bye mds")
    }

    //cant use unowned or weak here
    var decorator:((cell:CustomCell)->Void)?

    func tableView(tableView:UITableView,cellForRowAtIndexPath indexPath:NSIndexPath)->UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier(Identifier, forIndexPath: indexPath) as CustomCell

        decorator?(cell)
        return cell
    }

}

这样的视图控制器具有(并且想要)对该对象的强引用

import UIKit
class ViewController: UIViewController {

    var datasource:MagicDataSource? = MagicDataSource()

    deinit {
        println("bye ViewCon")
    }

    override func viewDidLoad() {

        super.viewDidLoad()
        datasource?.decorator = decorateThatThing
    }

    func decorateThatThing(cell:CustomCell) {

        //neither of these two are valid             
        //[unowned self] (cell:CustomCell) in
        //[weak self] (cell:CustomCell) in

        cell.theLabel.text = "woot"

    }
}

当您放弃视图控制器时,数据源将不会被释放,视图控制器也不会释放,因为它对视图控制器上的decorateThatThing函数有强烈的参考。

您可以在ViewController执行此操作,停止循环并让装饰器释放,但感觉很乱

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
     datasource?.decorator = nil
}

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    datasource?.decorator = decorateThatThing
}

所以问题是如何声明变量和/或函数以避免手动拆除数据源,以便在丢弃视图控制器时也释放关联的数据源。

1 个答案:

答案 0 :(得分:3)

而不是

datasource.decorator = decorateThatThing

您可以使用

datasource.decorator = { [unowned self] cell in
    self.decorateThatThing(cell)
}