Pierwsze pytanie dotyczy zakresu, w jakim chcesz mieć swoje stałe, czyli tak naprawdę dwa pytania:
- Czy te stałe są specyficzne dla jednej klasy, czy też ma sens umieszczanie ich w całej aplikacji?
- Jeśli są specyficzne dla klasy, czy są przeznaczone do użytku przez klientów klasy, czy tylko w ramach klasy?
Jeśli są specyficzne i wewnętrzne dla jednej klasy, zadeklaruj je jako static const
na początku pliku .m, na przykład:
static NSString *const MyThingNotificationKey = @"MyThingNotificationKey";
Jeśli odnoszą się do pojedynczej klasy, ale powinny być publiczne / używane przez inne klasy, zadeklaruj je tak, jak extern
w nagłówku i zdefiniuj je w .m:
//.h
extern NSString *const MyThingNotificationKey;
//.m
NSString *const MyThingNotificationKey = @"MyThingNotificationKey";
Jeśli powinny być globalne, zadeklaruj je w nagłówku i zdefiniuj w odpowiednim module, szczególnie dla tych stałych.
Możesz je łączyć i dopasowywać dla różnych stałych o różnych poziomach globalności, które chcesz, aby były, oraz dla różnych stałych globalnych, które po prostu nie pasują do siebie - możesz umieścić je w osobnych modułach, każdy z własnym nagłówkiem, jeśli chcieć.
Dlaczego nie #define
?
Stara odpowiedź brzmi: „makra nie mają informacji o typie”, ale dzisiejsze kompilatory są całkiem sprytne, jeśli chodzi o sprawdzanie typów literałów (do jakich makr rozwijają się), a także zmiennych.
Nowoczesna odpowiedź brzmi, ponieważ debugger nie będzie wiedział o twoich makrach. W [myThing addObserver:self forKey:MyThingNotificationKey]
poleceniu debugera nie można powiedzieć, czy MyThingNotificationKey
jest to makro; debugger może o tym wiedzieć tylko wtedy, gdy jest to zmienna.
Dlaczego nie enum
?
Cóż, rmaddy pobił mnie w komentarzach: enum
może definiować tylko stałe całkowite. Rzeczy takie jak numery identyfikatorów seryjnych, maski bitowe, kody czterobajtowe itp.
Do tych celów enum
jest świetny i absolutnie powinieneś go używać. (Nawet lepiej wykorzystywać te NS_ENUM
i NS_OPTIONS
makra ). W przypadku innych rzeczy, to trzeba użyć czegoś innego; enum
nie robi nic poza liczbami całkowitymi.
I inne pytania
Myślałem o zaimportowaniu pliku w pliku Reddit-Prefix.pch, aby stałe były dostępne dla wszystkich plików. Czy to dobry sposób na robienie rzeczy?
Prawdopodobnie nieszkodliwe, ale prawdopodobnie przesadne. Zaimportuj swoje nagłówki stałych tam, gdzie ich potrzebujesz.
Jakie są przypadki użycia każdego z tych rozwiązań?
#define
: Dość ograniczone. Szczerze mówiąc, nie jestem pewien, czy jest już dobry powód, aby używać tego do stałych.
const
: Najlepsze dla stałych lokalnych. Musisz także użyć tego dla tego, który zadeklarowałeś w nagłówku i teraz definiujesz.
static const
: Najlepsze dla stałych specyficznych dla plików (lub klas).
extern const
: Musisz tego użyć podczas eksportowania stałej w nagłówku.
Ponadto, jeśli używam extern const
, czy muszę importować plik, czy też stałe będą dostępne globalnie bez importowania pliku?
Musisz zaimportować plik w każdym pliku, w którym go używasz, lub w nagłówku prefiksu.