简体   繁体   English

这种情况会造成保留周期吗

[英]Will this situation create a retain cycle

My sample code like this (just a sample): 我的示例代码如下(只是一个示例):

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

The block is a parameter of a method, the method is a instance method of self.view , then I access self in block. 块是方法的参数,该方法是self.view的实例方法,然后我在块中访问self If self.view is a strong property, will this situation create retain cycle? 如果self.view是一个强大的属性,这种情况是否会造成保留周期? And will self.view strong reference the block? 并且self.view强引用该块吗?

Adding my comment above as answer, after testing the code myself to confirm the logic I mentioned, 在自己测试代码以确认我提到的逻辑后,在上面添加我的评论作为答案。

I think it should not, dead lock ( I mean memory leak, two strongly held objects holding the reference to each other and never being de-allocated hence I mentioned deadlock) will happen only if you pass a strong reference of an object to the block (in this case self) and then the passed object holds a strong reference to block itself (directly or indirectly). 我认为应该不会发生死锁(我的意思是内存泄漏,两个牢固保存的对象相互保持引用,并且永远不会取消分配,因此我提到了死锁)仅当您将对象的强引用传递给块时才会发生(在这种情况下为self),然后传递的对象(直接或间接)拥有强烈的对自身的引用。

Hoping that method touchActionWithCompeletion will not save the block passed to it with a strong reference this should not result in a retain cycle 希望方法touchActionWithCompeletion将不会使用强引用保存传递给它的块,这不应导致保留周期

EDIT: 编辑:

Tested your code and deinit gets called as expected. 测试您的代码,并按预期调用deinit。 Here is what I tried, 这是我尝试过的

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")
    }
}

As expected deinit called. 如预期的那样,deinit调用了。

Only thing to notice here, method touchActionWithCompeletion will not store the block passed to it with strong reference. 唯一需要注意的是,方法touchActionWithCompeletion不会存储具有强引用的传递给它的块。 It simply executes it. 它只是执行它。 So my answer above holds true in this case. 因此,我的上述回答在这种情况下适用。

EDIT 2:(Clarifying my statement in answer) 编辑2 :(澄清我的回答)

I happened mention the passed object holds a strong reference to block itself (directly or indirectly) I guess I need to explain why I mentioned indirectly . 我碰巧提到传递的对象(直接或间接地)对阻止自身有很强的引用,我想我需要解释为什么我间接提到了。

Consider this case, Deadlock will happen if View holds a strong reference to the block passed to its method. 考虑这种情况,如果View对传递给它的方法的块拥有强大的引用,则会发生死锁。 Though the strong object passed here to the block is self and self does not hold the reference to block directly, it still result in deadlock if View holds a strong reference to block. 尽管此处传递给块的强对象是self并且self不直接持有对块的引用,但如果View持有对块的强引用,则仍然会导致死锁。

Reason Self - holds a strong reference -> View - holds a strong reference -> Block - holds a strong reference -> Self 原因自我 -拥有强大的参考-> 视图 -拥有强大的参考-> 区块 -拥有强大的参考-> 自我

Hence deadlock. 因此陷入僵局。 Though self does not hold the block directly, because it holds the block indirectly, hence deinit on self will not be called. 尽管self不直接持有该块,但由于它间接持有该块,因此不会调用deinit上的deinit Hence I happened to mention the passed object holds a strong reference to block itself (directly or indirectly) 因此,我碰巧提到了传递的对象(直接或间接)拥有强大的引用来阻止自身

Hope it helps 希望能帮助到你

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM