2014-11-28 26 views
10

W przewodniku Adopting Modern Objective-C Apple zaleca używanie makra NS_ENUM zamiast wyliczenia. Przeczytałem również wyjaśnienie z NSHipster o NS_ENUM i NS_OPTIONS.typedef NS_ENUM vs typedef enum

Może ja coś przeoczyłem, ale nie bardzo rozumiem, co jest różnica między dwiema następującymi fragmentów i ewentualne dlaczego NS_ENUM zalecana droga (z wyjątkiem być może, dla wstecznej kompatybilności ze starszymi kompilatorów)

// typedef enum 
typedef enum { 
    SizeWidth, 
    SizeHeight 
}Size; 

// typedef NS_ENUM 
typedef NS_ENUM(NSInteger, Size) { 
    SizeWidth, 
    SizeHeight 
}; 
+0

Czy sprawdziłeś, co robi makro 'NS_ENUM'? – holex

+0

Przeczytałem, że "Makro" NS_ENUM "pomaga zdefiniować nazwę i typ wyliczenia, w tym przypadku o nazwie UITableViewCellStyle typu NSInteger. Typem wyliczeń powinien być NSInteger." Jedyną różnicą, jaką widzę w tym zdaniu, jest typ –

+2

Dlaczego nie sprawdzasz kodu źródłowego tego makra, aby uzyskać wskazówkę, to wszystko w Xcode jest dostępne za darmo i zajmuje jedno kliknięcie. – Andy

Odpowiedz

13

Po pierwsze, NS_ENUM używa nowej funkcji języka C, w której można określić podstawowy typ wyliczenia. W tym przypadku, podstawowym typem wyliczenia jest NSInteger (w zwykłym C będzie to niezależnie od tego, co zdecyduje kompilator, char, short, lub nawet 24-bitowa liczba całkowita, jeśli kompilator tak to odczuje).

Po drugie, kompilator specjalnie rozpoznaje makro NS_ENUM, więc wie, że masz wyliczenie z wartościami, które nie powinny być łączone jak flagi, debugger wie, co się dzieje, a wyliczenie może być automatycznie przetłumaczone na Swift.

10

NS_ENUM pozwala na zdefiniowanie typu. Oznacza to, że kompilator może sprawdzić, czy jesteś przypisując enum do innej zmiennej tak:

//OK in both cases 
NSInteger integer = SizeWidth; 
//OK only with typedef 
BOOL value = SizeHeight; 

NS_ENUM zapewnia również kontrole w switch sprawozdania, które zostały objęte wszystkie możliwe wartości:

//Will generate warning if using NS_ENUM 
switch(sizeVariable) { 
    case SizeWidth: 
     //Do something 
}