Первый вопрос заключается в том, какую область видимости вы хотите иметь для своих констант, а на самом деле это два вопроса:
- Являются ли эти константы специфичными для одного класса, или имеет смысл иметь их во всем приложении?
- Если они специфичны для класса, предназначены ли они для использования клиентами класса или только внутри класса?
Если они являются специфическими и внутренними для одного класса, объявите их static const
в начале файла .m следующим образом:
static NSString *const MyThingNotificationKey = @"MyThingNotificationKey";
Если они относятся к одному классу, но должны быть публичными / использоваться другими классами, объявите их как extern
в заголовке и определите их в .m:
//.h
extern NSString *const MyThingNotificationKey;
//.m
NSString *const MyThingNotificationKey = @"MyThingNotificationKey";
Если они должны быть глобальными, объявите их в заголовке и определите их в соответствующем модуле, специально для этих констант.
Вы можете смешивать и сопоставлять их для разных констант с разными уровнями того, насколько глобальными они вам нужны, и для разных глобальных констант, которые просто не связаны друг с другом - вы можете поместить их в отдельные модули, каждый со своим собственным заголовком, если вы хотеть.
Почему нет #define
?
Старый ответ - «у макросов нет информации о типе», но сегодня компиляторы достаточно умны в отношении выполнения всей проверки типов для литералов (то, к чему расширяются макросы), а также для переменных.
Современный ответ таков: отладчик не будет знать о ваших макросах. Вы не можете сказать [myThing addObserver:self forKey:MyThingNotificationKey]
в команде отладчика, MyThingNotificationKey
является ли макрос; отладчик может знать об этом, только если это переменная.
Почему нет enum
?
Что ж, rmaddy опередил меня в комментариях: enum
может определять только целочисленные константы. Такие вещи, как номера серийных идентификаторов, битовые маски, четырехбайтовые коды и т. Д.
Для этих целей enum
отлично подходит, и вы обязательно должны его использовать. (Еще лучше, если использовать те NS_ENUM
и NS_OPTIONS
макросы .) Для других вещей, вы должны использовать что - то другое; enum
не делает ничего, кроме целых чисел.
И другие вопросы
Я думал об импорте файла в файл Reddit-Prefix.pch, чтобы сделать константы доступными для всех файлов. Это хороший способ делать вещи?
Вероятно, безвреден, но, вероятно, чрезмерен. Импортируйте ваши константы заголовков, где они вам нужны.
Каковы варианты использования для каждого из этих решений?
#define
Довольно ограничен. Я, честно говоря, не уверен, что есть веская причина использовать это для констант больше.
const
: Лучше всего подходит для локальных констант. Кроме того, вы должны использовать это для того, который вы объявили в заголовке и теперь определяете.
static const
: Лучше всего подходит для констант, специфичных для файлов (или классов).
extern const
: Вы должны использовать это при экспорте константы в заголовке.
Также, если вы используете extern const
, нужно ли импортировать файл, или константы будут доступны глобально без импорта файла?
Вам необходимо импортировать файл, либо в каждый файл, в котором вы его используете, либо в заголовок префикса.