2012-01-30 82 views
12

我發現了各種各樣的人/文章(例如this SO answer),它們表明Objective-C中指針的值在您爲其指定某些內容之前未定義。但是,我發現在實踐中,他們將自動設置爲我叫alloc甚至在nil - 下面的代碼我運行,而無需斷言:指針是否始終設置爲零?

NSString* foo;   // 1 
assert(foo==nil);  // foo is nil 
foo = [NSString alloc]; // 2 
assert(foo!=nil);  // after alloc, not nil. 
foo = [foo init];  // 3 
assert(foo!=nil);  // still not nil 

可以/我應該靠這個?它是保證還是隻是碰巧在某種調試模式下運行我的編譯器(Xcode)? (我是Objective-C的新手)。

一個必然的問題:在標記爲1,2和3的行末尾描述foo的正確術語是什麼?我想至少有一個被稱爲'未初始化',並且其中一個'已初始化',但是其中,我們稱之爲第三個選項?

+0

頁頭對象之後進行初始化,通常不==零。等於零它是錯誤 – theWalker 2012-01-30 22:52:34

+1

可能的重複http://stackoverflow.com/questions/3989377/xcode-compiler-doesnt-set-my-variable-and-pointer-initial-value-to-0-or-nil – 2012-01-30 22:54:35

回答

25

ARC,所有對象指針在初始化設置爲nil。當不在ARC下運行時,或者在使用指向其他數據類型的指針時,未初始化的指針將具有垃圾值(實際上,根據C標準,從指針讀取會產生未定義的行爲)。


@Chuck指出了一些重要的東西,這就是說這隻適用於局部變量。任何具有靜態存儲(函數靜態或全局變量)和實例變量的變量總是被初始化爲它們各自的零值(對於指針,其值爲nil/NULL)。

+7

請注意,這隻適用於局部非靜態變量。根據標準,對象類型*的全局,靜態和實例變量將被初始化爲零。 – Chuck 2012-01-30 22:54:27

+0

@Chuck:非常好的一點。我會相應地更新我的答案。 – 2012-01-30 22:55:14

+0

你能鏈接到說明這個請求的文檔嗎?我認爲ARC鏈接會有它,但它似乎並不(我在頁面搜索'零') – bacar 2012-01-30 23:24:07

6

(電弧,看凱文的答案)

可以/我應該靠這個?

不是 - 永遠不要依賴那個。堆棧內存通常在調試版本中歸零(取決於您的編譯器設置)。啓用優化後,編譯器不會爲您執行此操作,並且會根據堆棧區域上最後存在的任何內容給出垃圾值。

可以依靠歸零ivars在你的對象的初始化。

您可以使用靜態分析器來防止自己陷入困境,並且在優化級別大於-O0時爲您的構建配置啓用-Wuninitialized

一個必然的問題:在標記爲1,2和3的行的末尾描述foo的正確術語是什麼?我想至少有一個被稱爲'未初始化',並且其中一個'已初始化',但是其中,我們稱之爲第三個選項?

  1. 未初始化
  2. 已分配,但尚未初始化(不可靠的,否則使用)
  3. 初始化的objc實例或對象的objc實例。
+0

I如果我能弄明白,那麼就試着打開它們,然後發回 - 只是爲了檢查,它是否也會禁用斷言? – bacar 2012-01-30 22:56:03

+0

@bacar:禁用斷言是通過'NS_BLOCK_ASSERTIONS'編譯器宏完成的。 – 2012-01-30 22:57:15

+0

是否曾經有過一個指針自動爲零的情況?如果沒有,這減輕了我關於發送消息到零的大多數顧慮... – bacar 2012-01-30 23:00:02

1

的回答你的推論問題:

後#1,富一直宣佈初始化

經過#2之後,foo已被分配爲但仍未未初始化

在#3之後,foo已被初始化爲

在實踐中,你永遠不想分開第2步和第3步,那就是你的代碼應該是foo = [[NSString alloc] init]。原因在於分配對象並不初始化或不正確地初始化對象是「危險」的。

如果你只是做這個foo = [NSString alloc]但忘記永遠調用init,使用foo是不安全的,因爲它沒有被初始化。同樣,這樣做[foo init](注意缺少重新分配給foo)也是不安全的,因爲init可以返回與最初由alloc分配的初始化對象不同的引用。

+0

這個術語是記錄在某個地方,或是一本書裏,或者只是你在社區中觀察到的東西? – bacar 2012-01-30 23:24:58

+0

這是標準的計算機科學術語。 – UIAdam 2012-01-30 23:25:52

+0

好的:-)我來自一個C++/C#背景,其中的對象或者是構造的,或者是不是 - 不在中間。 – bacar 2012-01-31 00:17:58

0

在ARC環境中,對象自動設置爲零。但是在初始化過程中爲對象賦值時總是一個好習慣。

我只是跑與OBJ-C測試中ARC環境

NSString *testStr ; 
if (testStr == nil) { 
    NSLog(@"Test Successful"); 
} 

OutPut :測試成功

NSString *testStr = nil; 
if (testStr == nil) { 
    NSLog(@"Test Successful"); 
} 

OutPut :測試成功