在块/块中使用weakSelf时的EXC_BAD_ACCESS

时间:2013-05-08 13:49:58

标签: objective-c objective-c-blocks exc-bad-access weak-references retain-cycle

我一直在讨论这个问题,因为我认为我完全不了解保留周期。我对此完全陌生,我正在努力了解更多信息。

我收到带有以下代码的EXC_BAD_ACCESS消息。

我开始使用weakSelf,因为如果我只使用self.successBLock();我会得到2个关于保留周期的警告。确切的警告是:

Capturing 'self' strongly in this block is likely to lead to a retain cycle

也许我甚至不愿意使用弱者,但我对此不太确定。

这是我在块中使用weakSelf的部分:

__weak Request *weakSelf = self;

[_operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    weakSelf.successBlock(operation.response, responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    weakSelf.failureBlock(operation.response, error);
}];

这就是我分配块属性的方法:

typedef void (^successBlock)(NSHTTPURLResponse *response, id responseObject);
typedef void (^failureBlock)(NSHTTPURLResponse *response, NSError *error);

@property (nonatomic, copy) successBlock successBlock;
@property (nonatomic, copy) failureBlock failureBlock;

2 个答案:

答案 0 :(得分:8)

__weak引用设置为nil,如果它指向的对象已取消分配。 因此,如果您的Request对象在完成块已被释放时已被释放 被叫weakSelfnil。在这种情况下,weakSelf.successBlock计算为NULL指针,这导致崩溃。

以下模式可以避免此问题:

[_operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    Request *strongSelf = weakSelf;
    if (strongSelf) {
        strongSelf.successBlock(operation.response, responseObject);
    }
} ...
如果strongSelf对象已被解除分配,则

nil将为Request。 否则,强引用可确保不释放对象 块正在执行。

另一方面,如果希望Request对象存在,直到完成块 被调用,那么你不应该使用弱引用。

答案 1 :(得分:0)

weakSelf设置为nil时,weakSelf.successBlock没问题,但weakSelf.successBlock(operation.response, responseObject)会崩溃。