Zajmuję się Cocoa aplikacji i używam stale NSString
s jako sposobów przechowywania nazwy klawiszy do moich preferencji.
Rozumiem, że to dobry pomysł, ponieważ w razie potrzeby umożliwia łatwą zmianę kluczy.
Ponadto jest to całe pojęcie „oddziel swoje dane od logiki”.
W każdym razie, czy istnieje dobry sposób, aby zdefiniować te stałe raz dla całej aplikacji?
Jestem pewien, że istnieje prosty i inteligentny sposób, ale teraz moje klasy po prostu redefiniują te, których używają.
Odpowiedzi:
Powinieneś utworzyć plik nagłówka jak
(możesz użyć
extern
zamiast,FOUNDATION_EXPORT
jeśli twój kod nie będzie używany w mieszanych środowiskach C / C ++ lub na innych platformach)Możesz dołączyć ten plik do każdego pliku, który używa stałych lub we wstępnie skompilowanym nagłówku projektu.
Zdefiniujesz te stałe w pliku .m, takim jak
Constants.m należy dodać do celu aplikacji / frameworka, aby był powiązany z produktem końcowym.
Zaletą używania stałych ciągowych zamiast stałych
#define
d jest to, że można sprawdzić równość za pomocą wskaźnika porównania (stringInstance == MyFirstConstant
), który jest znacznie szybszy niż porównanie ciągu ([stringInstance isEqualToString:MyFirstConstant]
) (i łatwiejszy do odczytania, IMO).źródło
NSString
którychcopy
zamiast definiować ich właściwościretain
. W związku z tym mogą (i powinny) przechowywać inną instancjęNSString*
stałej, a bezpośrednie porównanie adresu pamięci nie powiedzie się. Zakładam również, że każda rozsądnie optymalna implementacja-isEqualToString:
sprawdziłaby równość wskaźnika przed przejściem do drobiazgowości porównania znaków.Najprostszy sposób:
Lepszy sposób:
Jedną z zalet drugiej jest to, że zmiana wartości stałej nie powoduje przebudowy całego programu.
źródło
extern NSString const * const MyConstant
, tzn. Uczynienie go stałym wskaźnikiem do stałego obiektu, a nie tylko stałym wskaźnikiem?Jest też jedna rzecz do wspomnienia. Jeśli potrzebujesz stałej globalnej, powinieneś użyć
static
słowa kluczowego.Przykład
Ze względu na
static
słowo kluczowe ta stała nie jest widoczna poza plikiem.Drobna korekta @QuinnTaylor : zmienne statyczne są widoczne w jednostce kompilacyjnej . Zwykle jest to pojedynczy plik .m (jak w tym przykładzie), ale może cię ugryźć, jeśli zadeklarujesz go w nagłówku, który jest zawarty w innym miejscu, ponieważ po kompilacji wystąpią błędy linkera
źródło
Przyjęta (i poprawna) odpowiedź mówi, że „możesz dołączyć ten plik [Constants.h] ... do wstępnie skompilowanego nagłówka projektu”.
Jako nowicjusz miałem trudności z zrobieniem tego bez dalszego wyjaśnienia - oto jak: W pliku YourAppNameHere-Prefix.pch (jest to domyślna nazwa prekompilowanego nagłówka w Xcode) zaimportuj plik Constants.h wewnątrz
#ifdef __OBJC__
bloku .Zauważ też, że pliki Constants.h i Constants.m nie powinny zawierać w nich absolutnie nic poza opisanymi w zaakceptowanej odpowiedzi. (Brak interfejsu lub implementacji).
źródło
Ogólnie używam sposobu opublikowanego przez Barry'ego Warka i Rahula Gupta.
Chociaż nie lubię powtarzać tych samych słów w plikach .h i .m. Zauważ, że w poniższym przykładzie linia jest prawie identyczna w obu plikach:
Dlatego lubię korzystać z niektórych maszyn preprocesora C. Pozwól mi wyjaśnić na przykładzie.
Mam plik nagłówka, który definiuje makro
STR_CONST(name, value)
:W mojej parze .h / .m, w której chcę zdefiniować stałą, wykonuję następujące czynności:
et voila, mam wszystkie informacje o stałych tylko w pliku .h.
źródło
Sam mam nagłówek poświęcony deklarowaniu stałych NSStrings używanych w preferencjach, takich jak:
Następnie zadeklaruj je w dołączonym pliku .m:
To podejście mi dobrze służyło.
Edycja: Zauważ, że działa to najlepiej, jeśli ciągi są używane w wielu plikach. Jeśli używa go tylko jeden plik, możesz to zrobić
#define kNSStringConstant @"Constant NSString"
w pliku .m, który używa łańcucha.źródło
Niewielka modyfikacja sugestii @Krizz, aby działała poprawnie, jeśli plik nagłówka stałych ma być zawarty w PCH, co jest raczej normalne. Ponieważ oryginał jest importowany do PCH, nie załaduje go ponownie do
.m
pliku, a zatem nie otrzymasz żadnych symboli, a linker jest niezadowolony.Jednak następująca modyfikacja pozwala mu działać. To trochę skomplikowane, ale działa.
Potrzebne będą 3 pliki,
.h
plik ze stałymi definicjami,.h
plik i.m
plik, którego użyjęConstantList.h
,Constants.h
iConstants.m
odpowiednio. zawartośćConstants.h
jest po prostu:i
Constants.m
plik wygląda następująco:Wreszcie
ConstantList.h
plik zawiera rzeczywiste deklaracje i to wszystko:Kilka rzeczy do zapamiętania:
Musiałem ponownie zdefiniować makro w
.m
pliku po#undef
ing go do makro ma być używany.Musiałem także użyć
#include
zamiast#import
tego, aby działało to poprawnie i unikałem zauważenia przez kompilator wcześniej wstępnie skompilowanych wartości.Będzie to wymagało ponownej kompilacji twojego PCH (i prawdopodobnie całego projektu) za każdym razem, gdy jakiekolwiek wartości zostaną zmienione, co nie ma miejsca, jeśli zostaną one rozdzielone (i powielone) jak zwykle.
Mam nadzieję, że jest to pomocne dla kogoś.
źródło
extern
powyższe przezFOUNDATION_EXPORT
.źródło
Jak powiedział Abizer, możesz umieścić go w pliku PCH. Innym sposobem, który nie jest tak brudny, jest utworzenie pliku dołączania dla wszystkich kluczy, a następnie albo dołączenie go do pliku, w którym używasz kluczy, albo uwzględnienie go w PCH. Z ich własnym plikiem dołączającym, co najmniej daje jedno miejsce do wyszukiwania i definiowania wszystkich tych stałych.
źródło
Jeśli chcesz coś w rodzaju stałych globalnych; szybki i brudny sposób polega na umieszczeniu w
pch
pliku stałych deklaracji .źródło
Spróbuj użyć metody klasowej:
Czasem go używam.
źródło
isEqualToString:
porównania, które jest dodatkowy koszt w czasie wykonywania. Kiedy chcesz stałych, twórz stałe.Jeśli podoba Ci się stała przestrzeni nazw, możesz wykorzystać struct, piątek Pytania i odpowiedzi 2011-08-19: Stałe przestrzeni nazw i funkcje
źródło
__unsafe_unretained
kwalifikatorem, aby działał.Używam klasy singleton, aby móc wyśmiewać klasę i zmienić stałe, jeśli to konieczne do testowania. Klasa stałych wygląda następująco:
I jest używany w ten sposób (zwróć uwagę na użycie skrótu dla stałych c - za
[[Constants alloc] init]
każdym razem oszczędza pisania ):źródło
Jeśli chcesz wywołać coś takiego
NSString.newLine;
z celu c i chcesz, aby była stała statyczna, możesz szybko utworzyć coś takiego:I masz ładną, czytelną stałą definicję, dostępną z wybranego typu, podczas gdy styl jest ograniczony do kontekstu typu.
źródło