我正在使用 block 来处理非 ARC 项目中异步 http 请求的响应。代码如下所示(相关部分):
NSMutableUrlRequest* request = ...;
__block typeof(self) mutableSelf = self;
void (^didGetSessionBlock)(Gopher* newGopher) = ^(Gopher* newGopher) {
if (newGopher.statusCode == HTTP_OK) {
...
mutableSelf.retryOnFail = NO;
[mutableSelf executeRequest:request];
}
...
[mutableSelf setStatusCode:newGopher.statusCode];
};
Gopher* newGopher = [[[Gopher alloc] init] autorelease];
[newGopher setDidCompleteBlock:didGetSessionBlock];
[newGopher fetchSession:myApp.settings.userName password:myApp.settings.password];
使用 __block mutableSelf
以便我可以修改 block 内部的 self
(而不是 self
的副本)。如果我理解正确的话, __block
关键字还具有不保留 mutableSelf
的效果,因此在 block 执行时它可能已经被释放(这正是发生的情况) )。
如果我改变
[mutableSelf executeRequest:request];
到
[self executeRequest:request];
一切都很好,因为 self
被保留,并且在 block 执行之前不会被释放。但是,直接引用 self 可能会因保留周期而导致泄漏。
有办法解决这个问题吗?我应该在声明 mutableSelf
时手动保留它,然后在 block 内释放它吗?或者我应该在不修改的 block 内使用 self ,从而可能造成泄漏?这两种变体看起来都很脆弱,需要在注释中进行解释,以避免在代码修改时出现混淆和 future 的错误。
有办法解决这个问题吗?如果没有,最好的方法是什么?
最佳答案
你不能修改 block 中的self
,你只能修改它指向的对象。我认为您不需要 __block
。
关于objective-c - 在 Objective-C 中保留 block 中的可变变量而不引起循环引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9783447/