我这样的示例代码(只是一个示例):
[self.view touchActionWithCompeletion:^(NSSting *text){
self.label.text = text;
}];
块是方法的参数,该方法是self.view
的实例方法,然后我在块中访问self
。如果self.view
是一个强大的财产,这种情况会创造保留周期吗?并且self.view
会强烈引用该块吗?
在我自己测试代码以确认我提到的逻辑之后,在上面添加我的评论作为答案,
我认为它不应该,死锁(我的意思是内存泄漏,两个持有对象的强烈持有的对象,永远不会被解除分配,因此我提到了死锁)只有当你将一个对象的强引用传递给块时才会发生(在这种情况下为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")
}
}
正如预期的那样,德尼特打来电
这里唯一需要注意的是,方法touchActionWithCompeletion
不会存储通过强引用传递给它的块。它只是执行它。所以我的答案在这种情况下也适用。
编辑2 :(澄清我在回答中的陈述)
我碰巧提到传递的对象持有强烈的引用来阻止它本身(直接或间接)我想我需要解释为什么我间接提到。
考虑这种情况,如果View持有对传递给其方法的块的强引用,则会发生死锁。虽然这里传递给块的强对象是self
,而self
不能直接阻塞对象的阻塞,但如果View
拥有对块的强引用,它仍会导致死锁。
理由自我 - 持有强烈的参考 - >视图 - 持有强大的参考 - >阻止 - 持有强大的参考 - >自我
因此陷入僵局。虽然self
不直接持有该块,因为它间接地持有该块,因此不会调用自己的deinit
。因此我偶然提到传递的对象持有强烈的引用来阻止它自己(直接或间接)
希望能帮助到你