2009-02-19 71 views
6

Objective-C中的單個下劃線顯然是爲Apple的「內部」使用保留的(並且可以在Apple聲明之前與私有實例變量一起使用)。但爲什麼他們會在iPhone的SQLiteBooks示例中使用double -underscore?看到這個片段來自MasterViewController.m採取:Cocoa中的這種雙下劃線是什麼

+ (EditingViewController *)editingViewController { 
    // Instantiate the editing view controller if necessary. 
    if (__editingViewController == nil) { 
     __editingViewController = [[EditingViewController alloc] initWithNibName:@"EditingView" bundle:nil]; 
    } 
    return __editingViewController; 
} 

有這個forum的雙下劃線使用提,因爲它涉及到C - 這是對「compier內部使用。」我想我沒有看到在這種情況下如何適用。

我需要一個ViewController在我的應用程序中表現得非常像SQLiteBooks示例項目中的一個,但是這種雙下劃線讓我感到困惑。

回答

20

C編譯器和Objective-C編譯器都不用任何其他變量名稱來區別帶有前導下劃線的變量名。單引號或雙引號下劃線只是一個約定並且有效地形成一個命名空間,非常類似NSString等Cocoa類中使用的NS前綴。

望着SQLiteBooks代碼,MasterViewController.m這個定義靜態全局變量:

// Manage the editing view controller from this class so it can be easily accessed from both the detail and add controllers. 
static EditingViewController *__editingViewController = nil; 

所以我的猜測是,SQLiteBooks的作者採用了雙領先下劃線來表示全局變量。

C編譯器(以及擴展Objective-C)保留名稱,以兩個下劃線和一個大寫字母開頭供編譯器供應商使用,給它們一個保留的名稱空間以用於全局變量和用於實現標準庫的函數,或引入新的非標準關鍵字__block

儘管SQLiteBooks代碼在技術上是有效的,但在我看來,它很容易與保留的名稱空間混淆。如果你確實重用了這段代碼,我建議重命名該變量(Xcode有一個很好的重命名重構,它會自動爲你做)。

2

這只是一個變量命名約定。它沒有什麼。這是程序編寫者提醒自己的一種方式,「這是一個私有變量」。

+0

那麼你是說現在Apple已經聲稱它已經被內部使用,現在它已經被替換掉了一個下劃線? – Meltemi 2009-02-19 18:46:02

+0

這忽略了問題的實際問題。 – 2009-02-19 18:46:33

+1

是的,它和Apple的單下劃線一樣。 (不,安德魯,我不相信自己錯過了這一點,他問他們爲什麼使用雙下劃線,我解釋過。) – Chuck 2009-02-19 18:52:53

0

編譯器/庫供應商將某些前/後綴表示爲「保留」的情況並不少見。這主要是爲了避免類型/定義/繼承變量之間的無意的衝突。

你引用的帖子是關於定義,而不是變量。許多編譯器對它們提供和依賴的定義使用雙下劃線。

至於爲什麼它的示例代碼使用這種風格 - 原作者使用相同的編碼風格,他可能在日常工作中使用,潛在的衝突從未突出。

你應該很好地保留代碼示例,但如果它讓你感到不舒服,那麼你可以重命名該變量。

6

對於編譯器,下劃線被視爲任何字母字符。更一般地說,下劃線通常由語言擴展或大型庫使用,以避免與用戶代碼衝突。

使用下劃線是有問題的,因爲很多組嘗試使用特定的下劃線組合來保留每個名稱。

Apple傳統上使用一個下劃線前綴來表示一個私有實例變量(面嚮對象語言中的一種常見樣式)。這意味着每個人都應該給他們的ivars加下劃線,直到Apple指出在Apple代碼中使用下劃線可能會與Cocoa產生衝突,如果Apple決定改變他們的頭文件,也許你不應該這樣做。因此,下劃線前綴已經成爲「不建議」的編碼實踐。

在C和C衍生語言中,任何帶有雙下劃線前後兩個字的詞都是非標準語言擴展。請參閱Apple的擴展,如__attribute__

尾隨下劃線通常作爲編譯器或調試器名稱的原始名稱的損壞版本(特別是在編譯器爲多路傳輸時)添加並且通常被避免,以便這些名稱與原始文件明顯不同。谷歌將它們的Objective-C本地實例變量後綴加下劃線,以避免與Apple的下劃線發生衝突。

我的建議:不要使用下劃線。你不應該使用與實例變量同名的局部變量(這只是令人困惑)。唯一的潛在衝突是setter方法中的參數與相應的實例變量之間的衝突 - 您應該在參數前面加上小寫的「a」,「new」(或類似的),因爲這明確指出參數是傳入值但還不是「價值」。

相關問題