这种情况是否会产生保留周期

问题描述 投票:1回答:1

我这样的示例代码(只是一个示例):

[self.view touchActionWithCompeletion:^(NSSting *text){
    self.label.text = text;
}];

块是方法的参数,该方法是self.view的实例方法,然后我在块中访问self。如果self.view是一个强大的财产,这种情况会创造保留周期吗?并且self.view会强烈引用该块吗?

ios objective-c
1个回答
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")
    }
}

正如预期的那样,德尼特打来电

这里唯一需要注意的是,方法touchActionWithCompeletion不会存储通过强引用传递给它的块。它只是执行它。所以我的答案在这种情况下也适用。

编辑2 :(澄清我在回答中的陈述)

我碰巧提到传递的对象持有强烈的引用来阻止它本身(直接或间接)我想我需要解释为什么我间接提到。

考虑这种情况,如果View持有对传递给其方法的块的强引用,则会发生死锁。虽然这里传递给块的强对象是self,而self不能直接阻塞对象的阻塞,但如果View拥有对块的强引用,它仍会导致死锁。

理由自我 - 持有强烈的参考 - >视图 - 持有强大的参考 - >阻止 - 持有强大的参考 - >自我

因此陷入僵局。虽然self不直接持有该块,因为它间接地持有该块,因此不会调用自己的deinit。因此我偶然提到传递的对象持有强烈的引用来阻止它自己(直接或间接)

希望能帮助到你

© www.soinside.com 2019 - 2024. All rights reserved.