2012-07-09 30 views
0

我在自定義類中重寫- (BOOL) isEqual:(id)object__strong或__weak(或其他)參數時覆蓋-isEqual:?

出了4點的選擇,這是__weak__strong__autoreleasing,並__unsafe_unretained,應予使用上的isEqual:方法簽名的參數?

我在想這是問題所在,因爲當我試圖將我的類的一個實例添加到NSMutableDictionary時,我在該方法的聲明中得到了一個EXC_BAD_ACCESS(code=2, address=0x10)。任何方法主體的執行之前

- (BOOL) isEqual:(id __strong)object { 

換言之,線在該調試器獲取EXC_BAD_ACCESS是。

+1

Objective-C對象引用類型的任何聲明都隱含地包含__strong,所以我認爲你並不是問題所在。函數簽名應該保持與其覆蓋的函數相同。您很可能會將消息傳遞給已釋放或其指針已損壞的對象。我建議在你的代碼上運行Analyzer並修復發現的任何問題。 – jtomschroeder 2012-07-09 18:34:05

+1

默認情況下對象很強。如果您的訪問不暢,那麼您正在嘗試讀取或寫入一個沒有您認爲其內容的區域。 – Dustin 2012-07-09 18:34:58

+0

你是對的。註釋掉函數體並返回「NO」一致使錯誤消失。謝謝! – ryanrhee 2012-07-09 19:12:31

回答

1

正確的答案是「如果你訪問不良,那麼你正試圖讀取或寫入一個沒有你想象的區域。」,每@Dustin Rowland在註釋。

0

默認情況下,ARC使用__strong,這意味着該參數通過保留/釋放在方法內部使用期間持有。若要導致EXC_BAD_ACCESS,則在訪問它時必須過度釋放一個對象(參數本身或在isEqual:實現中方法中使用的任何其他對象)。這不能通過更改限定符來解決。

旁註:請小心,但是當您更改限定符時希望看到任何更改。編譯器優化可能會決定跳過一些調用是安全的。例如,將以下代碼添加到文件中,然後查看存檔(使用-Os)的程序集(產品 - >生成輸出 - >程序集文件)。

- (void)logObject:(id)o 
{ 
    NSLog(@"%@", o); 
} 

- (void)call 
{ 
    id o = [[NSObject alloc] init]; 
    [self logObject:o]; 
} 

雖然logObject:參數是默認__strong,沒有保留/釋放組件中輸出就完成了。將-logObject:的參數更改爲__strong,__weak,__unsafe_unretained__autoreleasing給出了完全相同的裝配輸出。但是,如果您使用NSLog複製該行,則會針對不同的類型限定符更改彙編代碼。

+0

這是一個有趣的現象,但我不會基於程序集文件得出結論。除非必要,否則預處理器不會添加-retain:和-release:調用嗎?至少,這就是我想象的ARC的工作原理。 – ryanrhee 2012-07-13 00:39:41

+0

@ ryanrhee90作爲一個例子,採取'__autoreleasing'應該總是添加對象到autorelease池。它確實發生在局部變量上,它不會發生在參數上。 – 2012-07-13 19:46:08

+1

@ ryanhee90我重新檢查了一個更復雜的例子,你是對的:'__strong','__weak'和'__unsafe_unretained'有所作爲。我無法想出任何「__autoreleasing」有什麼區別的例子。 – 2012-07-17 20:50:21