在块中保留可变变量而不会导致Objective-C中的保留周期

时间:2012-03-20 08:24:13

标签: objective-c memory-management retain 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以便我可以修改块内的self(而不是self的副本)。如果我理解正确的话,__block关键字也会导致mutableSelf不被保留,因此当块执行时它可能已经被释放(这正是发生的事情)。

如果我改变

[mutableSelf executeRequest:request];

[self executeRequest:request];

一切都很好,因为self被保留,并且在块执行之前不会被释放。但是,直接引用self可能会因保留周期而导致泄漏。

有解决方法吗?我应该在声明时手动保留mutableSelf,然后在块中释放它吗?或者我应该在我没有修改它的块中使用self,可能会造成泄漏?这两个变体看起来都很脆弱,需要在注释中进行解释,以避免在代码被修改时出现混淆和未来错误。

有没有办法解决这个问题?如果没有,最好的方法是什么?

1 个答案:

答案 0 :(得分:3)

您不会修改块中的self,只修改它指向的对象。我认为你不需要__block