现在我有一部分代码如下:
__strong MyRequest *this = self;
MyHTTPRequestOperation *operation = [[MyHTTPRequestOperation alloc]initWithRequest:urlRequest];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *request, id responseObject) {
[this requestFinished:request];
}
failure:^(AFHTTPRequestOperation *request, NSError *error) {
[this requestFailed:request withError:error];
}];
我主要是这样做的,因为其他一些类继承自此代码所在的类,并实现了自己的requestFinished和requestFailed。
如果我将自引用更改为__weak,我会开始收到一些EXC_BAD_ACCESS错误。使用__strong引用一切正常,但我担心创建一个保留周期。 请注意,我正在使用ARC。
此代码是否会创建一个会导致问题的保留周期?任何简单的解决方案?我可以遵循任何不同的方法让继承类实现自己的方法来处理响应吗?
答案 0 :(得分:11)
是的,它会创建一个保留周期。它会导致问题吗?也许
如果API支持它,您可以重置处理程序,这将手动打破保留周期:
[operation setCompletionBlockWithSuccess:nil failure:nil];
或者您可以使用弱引用。但是,你说你尝试了一个弱引用,它崩溃了。弱引用保证在消息开头是nil,或者在消息处理之前保持有效。换句话说,考虑......
__weak MyRequest *weakSelf = self;
dispatch_async(someQ, ^{
[weakSelf doSomething];
});
如果异步块执行时weakSelf
为nil,则“无”发生。如果它不是零,那么保证至少保留到doSomething
完成。实际上,它与此类似:
__weak MyRequest *weakSelf = self;
dispatch_async(someQ, ^{
{ id obj = weakSelf; [weakSelf doSomething]; obj = nil; }
});
但请注意,如果您这样做:
__weak MyRequest *weakSelf = self;
dispatch_async(someQ, ^{
[weakSelf doSomething];
[weakSelf doSomethingElse];
});
该对象可能在doSomething
和doSomethingElse
之间变为零。
此外,如果您通过弱引用访问实例变量,那么您只需要一个SEGV:
__weak MyRequest *weakSelf = self;
dispatch_async(someQ, ^{
foo = weakSelf->someIVar; // This can go BOOM!
});
因此,如果您的处理程序正在访问单个消息的弱引用,那么您应该没问题。其他任何东西都应该做“弱强舞”。
__weak MyRequest *weakSelf = self;
dispatch_async(someQ, ^{
MyRequest *strongSelf = weakSelf;
if (!strongSelf) return;
[strongSelf doSomething];
[strongSelf doSomethingElse];
foo = strongSelf->someIVar;
});
如果您认为自己遵循了这些准则,那么可能是一个更完整的源代码示例,其中包含崩溃详细信息会有所帮助......