Перечисление определяющих форм в Objective-C - PullRequest
36 голосов
/ 14 сентября 2011

В чем разница между

typedef enum {
    ...
} Name;

и

enum {
    ...
};
typedef NSUInteger Name;

?Если функциональность одинакова, для чего нужна вторая форма?Разве это не излишне грязно?

Ответы [ 2 ]

84 голосов
/ 15 сентября 2011

enum столько же лет, сколько C, поэтому является частью Objective-C.Это просто явное кодирование типа int.Это довольно полезно для отладки, и большинство новых компиляторов могут делать оптимизации на его основе.(Что вы должны полностью игнорировать).Это наиболее полезно для того, чтобы сделать ваш код более читабельным (кому-либо еще или себе после того, как вы выспались). За

typedef enum {
    ...
} NameType ;

последует

NameType name;

, и обычно этопредпочтительный стиль typedef,

ваш второй пример будет не связывать typedef со значениями, которые вы хотите указать, должен быть только данного типа.

Обратите внимание, что этоне мешает вам выполнить

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

, но в этом случае некоторые компиляторы могут выдавать предупреждение:


Сегодня я столкнулся с тем, что Apple использует следующее:

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

Они делают это, потому что действительно хотят, чтобы NSFetchedResultsChangeType был того типа, который они определили как NSUInteger.Это может быть int, но может быть и чем-то другим.И со значениями 1, 2, 3 и 4, это несколько не имеет отношения к us , что это за тип.Но они кодируют на другой уровень абстракции, потому что они являются поставщиком инструментов.

Вам никогда не следует обращаться к Apple за подсказками в стиле кодирования. Если вы видите что-то, что выглядит чище /лучший способ кодирования, это обычно так.Как упомянул Кевин, стабильность API для них имеет первостепенное значение.


Редактировать (январь 2013 г.) Если у вас есть доступ к Видео сессий WWDC 2012, вы должны посмотреть Session 405 - Modern Objective-C6: 00-10: 00.Обсуждается новый синтаксис в новом компиляторе, который позволяет явно определять размер типа и тесно связывать значения с типами.(заимствовано из C ++ 11)

enum NSFetchedResultsChangeType : NSUInteger {
NSFetchedResultsChangeInsert = 1,
NSFetchedResultsChangeDelete = 2,
NSFetchedResultsChangeMove = 3,
NSFetchedResultsChangeUpdate = 4
};
9 голосов
/ 14 сентября 2011

Первый определяет имя типа для ссылки на перечисление. Именно так большинство перечислений названы в C. Последнее немного отличается, и это распространено в рамках Cocoa. Есть две причины использовать последний. Во-первых, если ваше перечисление определяет битовое поле, и вы бы хотели его здесь, потому что, когда вы предоставляете значение «Имя», вы будете предоставлять комбинацию значений перечисления. Другими словами, если вы скажете что-то вроде

[self doSomethingWithBitfield:(Enum1 | Enum2)]

вы передаете не значение Name, а целое число, которое является комбинацией двух.

Тем не менее, инфраструктуры Какао используют эту идиому даже для значений, не являющихся битовыми полями, по очень веской причине: стабильность API. В соответствии со стандартом C базовый интегральный тип перечисления должен содержать все значения в перечислении, но компилятор выбирает иное. Это означает, что добавление нового значения перечисления может изменить интегральный тип перечисления (например, добавление -1 может сделать его подписанным, добавление 6 миллиардов может сделать его длинным и т. Д.). Это плохо с точки зрения стабильности API, потому что кодирование типов методов, которые принимают значения этого перечисления, может неожиданно измениться и потенциально сломать существующий код и двоичные файлы. Чтобы предотвратить это, платформы Какао обычно определяют тип как NSUInteger (или NSInteger, если им нужны отрицательные числа), поэтому API и кодировки типов остаются стабильными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...