在阅读 blog about concurrency 时在 iOS 中,我偶然发现了下一个代码:
__weak id weakSelf = self;
[self.operationQueue addOperationWithBlock:^{
NSNumber* result = findLargestMersennePrime();
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
MyClass* strongSelf = weakSelf;
strongSelf.textLabel.text = [result stringValue];
}];
}];
作者解释说需要使用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). Within the block we
convert it back to a strong reference to make sure it doesn’t get
deallocated while running the block.
我可以理解为什么该 block 会保留自己,但我不明白为什么(以及确切地在哪里)私有(private)操作队列保留了该 block 以及 self 何时/何地保留了操作队列。任何解释将不胜感激。
Best Answer-推荐答案 strong>
尝试在没有弱引用的情况下编写此代码:
[self.operationQueue addOperationWithBlock:^{
NSNumber* result = findLargestMersennePrime();
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.textLabel.text = [result stringValue];
}];
}];
为了使这段代码工作 - 编译器在 operationQueue 中保留对 self 的引用,以避免 self 从内存中删除和 的情况self.textLabel.text = .. 被执行,所以它试图保证对象是活着的。
这是实际创建循环的地方:
- self 保留 operationQueue(这意味着在 self 活着的时候不能删除 operationQueue)
- operationQueue 保留 self(这意味着在 operationQueue 处于事件状态时无法删除 self)
为避免这种情况 - 您正在创建周引用,因此您正在消除第二次保留
PS。 “block”是 operationQueue 的一部分,所以我们可以假设这个方案中只有 2 个项目。
关于ios - 使用操作队列保留循环,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/23149084/
|