2011-09-14 53 views
36

是什麼枚舉在Objective-C定義形式

typedef enum { 
    ... 
} Name; 

enum { 
    ... 
}; 
typedef NSUInteger Name; 

之間的區別?如果功能相同,那麼第二種形式有什麼好處?這不是不必要的混亂嗎?

+1

第二個從NSUInteger派生出一個類型,而不是第一個。 – 2011-09-14 19:02:58

回答

84

enumC一樣早,因此是Objective-C的一部分。 這只是一個int類型的明確編碼。這對調試非常有用,大多數較新的編譯器可以基於它進行優化。 (你應該完全忽略)。這對於提高代碼的可讀性(對任何人來說,或在你睡覺之後對你自己來說)都是非常有用的。

typedef enum { 
    ... 
} NameType ; 

之後將

NameType name; 

,這就是典型的一個typedef的首選風格,

你的第二個例子扳平的typedef要指定的值應該只有給定的類型。

請注意,這並不妨礙你從執行

name = 10244; // some non-valid value not listed in the enumeration 

但一些編譯器可能會產生在這種情況下警告,


我蘋果電腦公司今天使用以下的跑:

enum { 
NSFetchedResultsChangeInsert = 1, 
NSFetchedResultsChangeDelete = 2, 
NSFetchedResultsChangeMove = 3, 
NSFetchedResultsChangeUpdate = 4 
}; 
typedef NSUInteger NSFetchedResultsChangeType; 

他們這樣做是因爲他們真的希望NSFetchedResultsChangeType是它們定義爲NSUInteger的類型。這可以是一個int但它也可以是別的東西。並且值1,2,3和4,它與us有些不相關。但他們正在編碼到不同的抽象層次,因爲他們是工具提供者。

您絕對不應該期待Apple提供編碼風格提示。如果你看到一些看起來更清潔/更好的編碼方式,通常是這樣。正如凱文提到的那樣,API的穩定性對他們來說極爲重要。


編輯(2013年1月)如果您有機會獲得WWDC 2012會話視頻,你應該看Session 405 - Modern Objective-C 6:00-10:00。在較新的編譯器中討論了一種新的語法,它允許明確地確定類型的大小以及將值緊密結合到類型中。 (借用C++ 11)

enum NSFetchedResultsChangeType : NSUInteger { 
NSFetchedResultsChangeInsert = 1, 
NSFetchedResultsChangeDelete = 2, 
NSFetchedResultsChangeMove = 3, 
NSFetchedResultsChangeUpdate = 4 
}; 
+0

我正在製作我自己的iOS函數庫,目的是出售它們。那麼,我認爲我應該反對你的粗體評論,並遵循蘋果的風格? – ArtOfWarfare

+0

@ArtOfWarfare取決於目標的廣度,答案可能會有所不同。如果您還將定位到非Apple環境,則您的頭文件可能會包含各種語法混淆。如果你只是針對蘋果,我的意見是不遵循蘋果的領先 - 這是長期規劃。它會給你帶來的唯一好處就是對目前沒有人預見到的一些假設架構的支持。其他人肯定會不同意我的看法。 (除此之外:蘋果公司通常會建立在研究架構之上 - 這是他們架構不可知論的另一個原因)。 – bshirley

+0

感謝WWDC說明! –

9

前者定義了一個類型名稱來引用一個枚舉。這是大多數枚舉以C命名的方式。後者雖然有點不同,但它在Cocoa框架中很流行。使用後者有兩個原因。首先是如果你的枚舉定義了一個位域,並且你想在這裏,因爲當你提供一個「名稱」值時,你將提供枚舉值的組合。換句話說,如果你這樣說

[self doSomethingWithBitfield:(Enum1 | Enum2)] 

你不及格名稱的值,而是一個整數,是兩者的結合。

然而,Cocoa框架甚至爲非位域值使用這個習慣用法,這是一個很好的理由:API穩定性。根據C標準,枚舉的基本整型需要能夠包含枚舉中的所有值,但編譯器會另行選擇。這意味着添加一個新的枚舉值可能會改變枚舉的整型(例如,加-1可以使它被簽名,增加60億可以使它變成很長的等等)。從API穩定性的角度來看,這是一件壞事,因爲採用此枚舉值的方法的類型編碼可能會意外更改,並有可能破壞現有代碼和二進制文件。爲了防止這種情況發生,Cocoa框架通常將類型定義爲NSUInteger(或NSInteger,如果它們需要負數),所以API和類型編碼保持穩定。