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

时间:2018-01-02 07:41:29

标签: ios objective-c

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

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

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

1 个答案:

答案 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拥有对传递给其方法的块的强引用,则会发生死锁。虽然此处传递给块的强对象是selfself不能直接阻止对块的引用,但如果View拥有对块的强引用,它仍然会导致死锁。

原因自我 - 拥有强大的参考资料 - > 查看 - 拥有强大的参考资料 - > 阻止 - 拥有强大的参考资料 - > 自我

因此陷入僵局。虽然self不直接保存块,但因为它间接保存块,因此不会调用self上的deinit。因此我偶然提到传递的对象拥有强大的引用来阻止自身(直接或间接)

希望有所帮助