2

由于我不认为我完全理解保留周期,所以我一直在为这个问题而苦苦挣扎。我对这个完全陌生,我想了解更多信息。EXC_BAD_ACCESS当在块中使用weakSelf时

我使用以下代码获取EXC_BAD_ACCESS消息。

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

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; 
+0

你得到的错误确切的线。 – 2013-05-08 13:59:19

+0

关于这两行: weakSelf.successBlock(operation.response,responseObject); weakSelf.failureBlock(operation.response,error); – Nipje 2013-05-08 14:02:38

回答

7

如果对象A __weak参考值设置为nil它指向已被释放。 因此,如果您的Request对象已被释放,当完成块为 时,weakSelfnil。在这种情况下weakSelf.successBlock评估为NULL指针,并导致崩溃。

以下模式避免了这个问题:

[_operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { 
    Request *strongSelf = weakSelf; 
    if (strongSelf) { 
     strongSelf.successBlock(operation.response, responseObject); 
    } 
} ... 

strongSelfnil如果Request对象已经被释放。 否则,强引用可确保在块正在执行时不会释放对象 。

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

+0

当我尝试你的模式,它永远不会进入if语句。它确实进入失败或成功块。你知道这是什么原因吗? 此外,当我__weak更改__strong代码似乎工作。这只是我尝试过的,我不确定这是否是正确的解决方案。 – Nipje 2013-05-08 14:12:17

+0

@ user2362596:在块中使用'self'可以是正确的解决方案(这就是我的答案中最后一句话的意思)。在操作正在执行时,您将有一个“临时保留周期”。一旦操作完成并且完成块被调用,被捕获的自己就消失了,并且保留周期被中断。 – 2013-05-08 14:16:22

+0

但是这给我留下了你通常不希望的警告:在这个区块强烈地捕捉'自我'很可能导致保留周期。我知道我可能应该忽略这个警告,但是有什么办法让这个消息不显示吗? – Nipje 2013-05-08 14:27:07

0

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

相关问题