使用操作队列保留周期

时间:2014-04-18 07:01:14

标签: ios nsoperationqueue

在iOS中阅读blog about concurrency时,我偶然发现了下一个代码:

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

作者解释说,因为需要使用weakref:

  

我们需要对self进行弱引用,否则我们会创建一个retain   循环(块保留自身,私有操作队列保留   阻止,并自行保留操作队列)。在块内我们   将其转换回强引用,以确保它不会得到   在运行块时解除分配。

我可以理解为什么该块会保留self,但我不明白为什么(以及确切地说)私有操作队列保留块以及何时/ where self保留操作队列。任何解释都将非常感激。

1 个答案:

答案 0 :(得分:1)

尝试编写此代码而不使用弱引用:

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

使此代码有效 - 编译器保留对selfoperationQueue的引用,以避免从内存中删除self并执行self.textLabel.text = ..时的情况,因此它会尝试保证对象活着。

这是实际创建周期的地方:

  1. 自我保留operationQueue(这意味着当self还活着时无法删除operationQueue)
  2. operationQueue保留self(这意味着当operatorQueue还活着时不能删除self)
  3. 要避免这种情况 - 您正在创建周参考,因此您将消除第二次保留

    PS。 “block”是operationQueue的一部分,因此我们可以假设这个方案中只有2个项目。