简体   繁体   English

通过操作队列保持周期

[英]Retain cycle with an operation queue

While reading a blog about concurrency in iOS, I stumbled upon the next code: 在阅读有关 iOS 并发性博客时 ,我偶然发现了下一个代码:

__weak id weakSelf = self;
[self.operationQueue addOperationWithBlock:^{
    NSNumber* result = findLargestMersennePrime();
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        MyClass* strongSelf = weakSelf;
        strongSelf.textLabel.text = [result stringValue];
    }];
}];

The author explains that the use of weakref is needed since: 作者解释说,由于以下原因,需要使用weakref:

we need to make a weak reference to self, otherwise we create a retain cycle (the block retains self, the private operation queue retains the block, and self retains the operation queue). 我们需要弱引用self,否则我们将创建一个保留周期(块保留self,私有操作队列保留该块,而self保留操作队列)。 Within the block we convert it back to a strong reference to make sure it doesn't get deallocated while running the block. 在该块内,我们将其转换回强引用,以确保在运行该块时不会将其释放。

I can understand why the block would have retained self, but I don't understand why (and where exactly) the private operation queue retains the block and when/where self retaind the opeation queue. 我能理解为什么块会保留自身,但我不理解为什么私有操作队列会(以及确切地在何处)保留该块,以及何时/何处自我会保留操作队列。 Any explanation would be much appreciated. 任何解释将不胜感激。

try to write this code without weak reference: 尝试在没有弱引用的情况下编写以下代码:

[self.operationQueue addOperationWithBlock:^{
    NSNumber* result = findLargestMersennePrime();
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        self.textLabel.text = [result stringValue];
    }];
}];

to make this code work - compiler retains reference to self in operationQueue to avoid situation when self is deleted from memory and self.textLabel.text = .. is executed, so it tries to guarantee that object will be alive. 为了使此代码有效-编译器在operationQueue保留对self引用,以避免在从内存中删除self并执行self.textLabel.text = ..时发生这种情况,因此它试图确保对象保持活动状态。

This is where cycle is actually created: 这是实际创建周期的地方:

  1. self retains operationQueue (this means that operationQueue cannot be deleted while self is alive) self保留operationQueue(这意味着self处于活动状态时无法删除operationQueue)
  2. operationQueue retains self (this means that self cannot be deleted while operationQueue is alive) operationQueue保留self(这意味着operationQueue处于活动状态时无法删除self)

to avoid this - you're creating week reference, so you're eliminating 2nd retention 为避免这种情况-您正在创建周参考,因此消除了第二次保留

PS. PS。 "block" is part of operationQueue, so we can assume just 2 items in this scheme. “ block”是operationQueue的一部分,因此在该方案中我们只能假设2个项目。

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

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