3

现在我有一部分代码是这样的:

__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。

此代码是否会创建会导致问题的保留周期?有什么简单的解决方案吗?我可以遵循什么不同的方法让继承类实现自己的方法来处理响应?

4

1 回答 1

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];
});

对象可能在 和 之间变为doSomethingnil 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;
});

如果您认为您正在遵循指南,那么也许一个更完整的源代码示例以及崩溃详细信息会有所帮助......

于 2012-10-15T18:48:52.020 回答