我这样的示例代码(只是一个示例):
[self.view touchActionWithCompeletion:^(NSSting *text){
self.label.text = text;
}];
块是方法的参数,该方法是self.view
的实例方法,然后我在块中访问self
。如果self.view
是一个强大的属性,这种情况会创建保留周期吗?并且self.view
会强烈引用该块吗?
答案 0 :(得分:5)
在我自己测试代码以确认我提到的逻辑后,将上面的评论添加为答案,
我认为它不应该,死锁(我的意思是内存泄漏,两个强烈持有的对象持有彼此的引用而永远不会被解除分配,因此我提到了死锁)只有在你传递一个对象的强引用时才会发生到块(在本例中为self),然后传递的对象保持对块本身的强引用(直接或间接)。
希望方法touchActionWithCompeletion
不会使用强引用保存传递给它的块,这不应该导致保留周期
修改强>
测试您的代码并按预期调用deinit。 这是我试过的,
class MyView : UIView {
func touchActionWithCompeletion(block :(NSString)->()) {
block("abcd");
}
}
class ThirdViewController: UIViewController {
var myViewInstance = MyView()
@IBOutlet var c: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.myViewInstance.touchActionWithCompeletion { (abcd) in
self.c.text = abcd as String
}
}
deinit {
print("deinit called")
}
}
正如预期的那样,deinit打来电话。
此处只注意事项,方法touchActionWithCompeletion
不会存储使用强引用传递给它的块。它只是执行它。所以我的答案在这种情况下也适用。
编辑2 :(澄清我在回答中的陈述)
我碰巧提到传递的对象拥有阻止自身的强烈引用(直接或间接)我想我需要解释为什么我提到间接。
考虑这种情况,如果View拥有对传递给其方法的块的强引用,则会发生死锁。虽然此处传递给块的强对象是self
而self
不能直接阻止对块的引用,但如果View
拥有对块的强引用,它仍然会导致死锁。
原因自我 - 拥有强大的参考资料 - > 查看 - 拥有强大的参考资料 - > 阻止 - 拥有强大的参考资料 - > 自我
因此陷入僵局。虽然self
不直接保存块,但因为它间接保存块,因此不会调用self上的deinit
。因此我偶然提到传递的对象拥有强大的引用来阻止自身(直接或间接)
希望有所帮助