Перше питання - якою сферою ви хочете мати свої константи, а це справді два питання:
- Ці константи характерні для одного класу, чи має сенс їх мати протягом усього додатка?
- Якщо вони специфічні для класу, чи використовуються вони клієнтами класу чи лише в межах класу?
Якщо вони специфічні та внутрішні для одного класу, оголосіть їх як 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
, мені потрібно імпортувати файл, або константи будуть доступні в усьому світі без імпорту файла?
Вам потрібно імпортувати файл або в кожен файл, де ви його використовуєте, або в заголовок префікса.