防止Swift函数指针中的保留周期 [英] prevent retain cycle in Swift function pointers
问题描述
在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屋!