Typedef NS_ENUM vs typedef enum

В Принятие современного Objective-C руководства Apple рекомендует использовать макрос NS_ENUM вместо enum. Я также прочитал объяснение от NSHipster о NS_ENUM и NS_OPTIONS.

Возможно, я что-то пропустил, но я не совсем понимаю, в чем разница между следующими двумя фрагментами и если есть почему NS_ENUM рекомендуемый способ (за исключением, возможно, для обратной совместимости со старыми компиляторами)

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

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

Ответ 1

Во-первых, NS_ENUM использует новую функцию языка C, где вы можете указать базовый тип для перечисления. В этом случае базовым типом для перечисления является NSInteger (в простом C это будет то, что решает компилятор, char, short или даже 24-битное целое, если компилятор чувствует себя так).

Во-вторых, компилятор специально распознает макрос NS_ENUM, поэтому он знает, что у вас есть перечисление со значениями, которые не следует комбинировать как флаги, отладчик знает, что происходит, и перечисление может быть автоматически переведено в Swift.

Ответ 2

NS_ENUM позволяет вам определить тип. Это означает, что компилятор может проверить, назначает ли перечисление другой переменной, например:

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

NS_ENUM также предоставляет проверки в операторах switch, которые вы охватили все возможные значения:

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