OGeek|极客世界-中国程序员成长平台

标题: ios - 使用操作队列保留循环 [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-12 21:46
标题: ios - 使用操作队列保留循环

在阅读 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-推荐答案


尝试在没有弱引用的情况下编写此代码:

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

为了使这段代码工作 - 编译器在 operationQueue 中保留对 self 的引用,以避免 self 从内存中删除和 的情况self.textLabel.text = .. 被执行,所以它试图保证对象是活着的。

这是实际创建循环的地方:

  1. self 保留 operationQueue(这意味着在 self 活着的时候不能删除 operationQueue)
  2. operationQueue 保留 self(这意味着在 operationQueue 处于事件状态时无法删除 self)

为避免这种情况 - 您正在创建周引用,因此您正在消除第二次保留

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

关于ios - 使用操作队列保留循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23149084/






欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://sqlite.in/) Powered by Discuz! X3.4