gpt4 book ai didi

objective-c - 使用 ARC 在其自己的完成 block 中引用 NSOperation 对象

转载 作者:太空狗 更新时间:2023-10-30 03:21:20 24 4
gpt4 key购买 nike

我在将某些 NSOperation 代码转换为 ARC 时遇到困难。我的操作对象使用一个完成 block ,它又包含一个 GCD block ,用于更新主线程上的 UI。因为我从它自己的完成 block 中引用我的操作对象,所以我使用 __weak 指针来避免内存泄漏。但是,在我的代码运行时指针已经设置为 nil。

我已将范围缩小到此代码示例。有谁知道我哪里出错了,以及正确的方法吗?

NSOperationSubclass *operation = [[NSOperationSubclass alloc] init];
__weak NSOperationSubclass *weakOperation = operation;

[operation setCompletionBlock:^{
dispatch_async( dispatch_get_main_queue(), ^{

// fails the check
NSAssert( weakOperation != nil, @"pointer is nil" );

...
});
}];

最佳答案

另一种选择是:

NSOperationSubclass *operation = [[NSOperationSubclass alloc] init];
__weak NSOperationSubclass *weakOperation = operation;

[operation setCompletionBlock:^{
NSOperationSubclass *strongOperation = weakOperation;

dispatch_async(dispatch_get_main_queue(), ^{
assert(strongOperation != nil);
...
});
}];

[operationQueue addOperation:operation];

我假设您还将操作对象添加到 NSOperationQueue。在这种情况下,队列将保留一个操作。它也可能在执行完成 block 期间保留它(尽管我还没有找到关于完成 block 的官方确认)。

但是在你的完成 block 内部创建了另一个 block 。该 block 将在稍后的某个时间点运行,可能是在 NSOperations 的完成 block 运行结束之后。发生这种情况时,operation 将被队列释放并且 weakOperation 将为 nil。但是,如果我们从操作的完成 block 中创建对同一对象的另一个强引用,我们将确保 operation 在第二个 block 运行时存在,并避免保留循环,因为我们不捕获 operation block 变量。

Apple 在 Transitioning to ARC Release Notes 中提供了这个示例请参阅使用生命周期限定符避免强引用循环部分的最后一个代码片段。

关于objective-c - 使用 ARC 在其自己的完成 block 中引用 NSOperation 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9223049/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com