2009-11-18 33 views
3

這個問題的兩個部分Is if(obj && obj!= nil)是否正確且必要?

1)這是什麼理解是正確的?
「if(obj)」正在測試以查看指針是否不是0x0,也就是說設置爲整數存儲器地址
「if(obj!= nil)」將對象的內存地址與內存地址通用零對象

2) 所以在我不知道變量是否指向任何東西的情況下,如果是,我也不知道該對象是否是有效對象或無。我想根據這些信息做各種各樣的事情,而不僅僅是傳遞一個消息給obj,如果它是零,我會認爲它是安全的。這段代碼是否正確和必要?

if (obj && obj != nil) { 
    // Do a bunch of things that should only happen if obj is pointing to a valid object 
    [obj someMessage]; 
    [anotherObj someOtherMessage]; 
} 

謝謝你們!

回答

17

對不起?是。必要? No. Objective-C簡單地#define s nil(void *)0,它以C術語是錯誤的。所以乾脆寫作

if (obj) { 
    [obj someMessage]; 
    [anotherObj someOtherMessage]; 
} 

就足夠了。此外,由於Objective-C具有消息消息nil,您可以在某些情況下簡單地省略該支票。 (例如,如果第二行不在if塊中,則可以簡單地隨便撥打[obj someMessage]。)

+0

你怎麼'typedef'的價值? ;) –

+0

哎呦。固定。謝謝,帕維爾。 –

+0

一些其他的答案似乎是正確的,但我認爲這個解釋發生了什麼最好的工作。 – DougW

12

這是正確的,從某種意義上說,它會給你你期望的結果,但是是多餘的。這足以只需使用:

if (obj) { 

if (obj != nil) { 
+2

非常感謝您的回答。 upvoted爲正確,但我要標記本的解釋它背後的理由的答案。 – DougW

0

如果(OBJ ==零),那麼如果(OBJ)將評估假。你不需要兩個。

+0

對不起,我真的不是故意低估這個,因爲我點擊了英國偉哥的答案。我無法投票,因爲它已經太久了,但我在編輯帖子時將不投票。 – Joost

4

您可以簡單地使用if (obj)。根據objc.h,nil#define__DARWIN_NULL。撥打/usr/include/sys/_types.h,我們看到__DARWIN_NULL被定義爲0L0(void *)0,具體取決於平臺以及您是否使用C或C++編譯器。但最後,nil總是評估爲false,所以更簡單的if (obj)就足夠了。

4

不是直接回答你的問題,而是第2部分暗示的問題類型:除了發送消息並查看它是否執行了你的操作之外,沒有辦法知道指針是否引用「有效對象」想。有各種各樣的事物,不是零,但仍然不是什麼被認爲是大多數目的的「有效對象」。例如,一個對象變量可能指向:

  • 這裏曾經居住解分配對象的垃圾空間
  • 變量應該指向
  • 這項工作到位的對象被分配了一個新對象你不小心的變量設置爲
  • AC串的int,你不小心設置變量,而不是一個NSString的

有沒有辦法在運行時測試是否所有的這些都是CAS即你必須確保你的代碼沒有將變量放入類似狀態的錯誤。

+0

在開發過程中,您可以在XCode中打開NSZombieEnabled設置。在某些情況下,這會在所有無效指針位置創建NSZombie實例,NSZombie只會向您發送的所有消息拋出異常或給出其他主要錯誤指示。看到這個問題:http://stackoverflow.com/questions/535060/how-to-add-nsdebug-h-and-use-nszombie-in-iphone-sdk – harms

+0

澄清:NSZombieEnabled確實有助於追蹤這些類型的錯誤,但它不會在「所有無效的指針位置」創建NSZombie實例。它使'dealloc'把對象變成NSZombies,而不是實際釋放它們。當指針設置爲從不是對象的地址時,你仍然不會得到殭屍異常,就像我在我的答案中提到的int或C字符串示例。 – Chuck

+0

當然有。爲了我的目的,「有效的對象」意思是「對象的實例」。你可以使用[obj isKindOfClass:[ObjClass class]],如果它是零,那將是錯誤的。我只是認爲可能有一個obj!= nil的快捷方式。在我的情況下,我知道變量將永遠是未初始化的,無,或類X的實例。 – DougW

相關問題