【发布时间】:2016-08-14 05:37:40
【问题描述】:
这是我的自定义视图:
class CustomVIew: UIView {
deinit {
print("custom view deinit")
}
var onTapViewHandler: (()->Void)?
}
和视图控制器:
class ViewControllerB: UIViewController {
var customView: CustomVIew!
deinit {
print("B deinit")
}
override func viewDidLoad() {
super.viewDidLoad()
let customView = CustomVIew()
customView.onTapViewHandler = { [unowned self] in
self.didTapBlue()
}
customView.frame = CGRect(x: 50, y: 250, width: 200, height: 100)
customView.backgroundColor = UIColor.blueColor()
view.addSubview(customView)
self.customView = customView
}
func didTapBlue() {
}
}
当控制器从导航栈中弹出时,一切正常:
B deinit
custom view deinit
但是当我替换这段代码时:
customView.onTapViewHandler = { [unowned self] in
self.didTapBlue()
}
用这个:
customView.onTapViewHandler = didTapBlue
然后,控制台上不会打印任何内容。 CustomView 和 ViewController 没有发布,为什么?
为什么customView.onTapViewHandler = didTapBlue 会捕获对self 的引用?
【问题讨论】:
-
你知道为什么已经不是了吗?你的标题说它是保留圈...通过打印检查引用计数: print(CFGetRetainCount(object))
-
@当然你建议
CFGetRetainCount解决retain被弃用的问题。但是retain被弃用是有原因的:这不是一个好的解决方案。 -
这只是一种检查方法。我的意思是您可以打印出视图控制器被引用的引用量,以便您知道“customView”是否对视图控制器具有强引用。如果有,则有一个保留周期。因为它有一个retain循环,所以这两个对象不能被自动销毁。
-
@Surely 永远不要检查
CFGetRetainCount。你得到的信息没有用。例如,CFGetRetainCount导入 Swift 的方式使其所有结果都增加 1。永远不要检查保留计数。甚至文档都这么说。 -
@Sulthan 数量不重要,重要的是数量是否增加。我用它来计算引用,它有助于确定一行代码是否增加了对象的引用计数,因此我知道它是否会导致问题。而且这段代码只是为了调试,我并不是说你发布应用程序时会保留这段代码。不计参考,我很好奇你如何调试这样的问题?