防止Swift函数指针中的保留周期 [英] prevent retain cycle in Swift function pointers

查看:84
本文介绍了防止Swift函数指针中的保留周期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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
}

所以问题是我如何声明vars和/或函数以避免必须手动拆卸数据源,以便在丢弃视图控制器时也释放相关的数据源.

解决方案

而不是

datasource.decorator = decorateThatThing

您可以使用

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

How do I prevent a retain cycle when passing around functions as objects in Swift

Imagine you have a datasource object like this

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
    }

}

And a view controller like this which has (and wants) a strong ref to that object

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"

    }
}

When you discard the view controller , the datasource will not be released and neither will the view controller as it holds a strong ref to the decorateThatThing function on the view controller.

You can stop the cycle and get the decorator to release by doing this in ViewController but it feels messy

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

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

so the question is how do i declare vars and/or functions to avoid having to teardown the datasource manually so that when the view controller is discarded the associated datasource is released too.

解决方案

Rather than

datasource.decorator = decorateThatThing

You can use

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

这篇关于防止Swift函数指针中的保留周期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆