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)會崩潰。

相關問題