2009-08-19 14 views
7

Zastanawiam się, dlaczego Apple używa (całkiem w CoreAnimation, ale także w innych miejscach) stałych, które są zadeklarowane jako NSString * const, jak na przykład kCAGravityTop zamiast zwykłych wyliczeń? A co powiesz na bezpieczeństwo w tym przypadku? Jak rozumiem, można przekazać dowolny NSString do metody oczekującej tej stałej bez otrzymywania ostrzeżeń kompilatora.Powody używania stałych NSString do wyliczenia?

Odpowiedz

11

Nie jestem pewien, ale domyślam się, że ma to związek z dodawaniem przez użytkowników własnych rozszerzeń i podklas do niektórych produktów Apple. W takim przypadku możesz po prostu przesłonić używaną metodę i przechwycić przypadek, w którym ciąg znaków jest "MyOwnValue", a następnie zrobić, co chcesz z nim. Jest to znacznie łatwiejsze niż modyfikowanie wyliczenia firmy Apple, a także nie pozwala ci niczego podkręcać.

Może to również ułatwić Apple uzyskanie niezależności wersji. W przypadku wyliczenia, jeśli uporządkujesz ich kolejność w jakiś sposób, może to spowodować wiele problemów dla wszystkich wartości, które zostały zbuforowane (z jakiegokolwiek powodu). Jeśli wartość wyliczenia wynosi 1 < < 3, gdy jest zapisana w pliku, Apple dodaje kolejne wyliczenie, więc jego wartość wynosi teraz 1 < < 4, wtedy oczywiście z programu wychodzi niewłaściwa rzecz. Dlaczego nie byliby po prostu ostrożni, jeśli chodzi o przenoszenie wartości enum, nie wiem, ale myślę, że jest prawdopodobne, że użyli NSString, ponieważ nie ma możliwości, aby jego wartość lub kolejność mogła zostać zmieniona w dowolnej wersji.

+0

+1 Dobra hipoteza – h4xxr

+0

Dodatkowo uważam, że ważnym czynnikiem jest archiwizacja i archiwizacja.Teraz, gdy używane są frameworki, takie jak Core Data, można stwierdzić, że jeśli używane są wyliczenia, istnieje dużo boksowania i rozpakowywania, które mogą być brane pod uwagę, jeśli zamiast tego stosowane są łańcuchy, chociaż niektóre rozważania pozostają stałe dla stałych łańcuchowych - ciężar niepotrzebnych "hydraulika" jest zmniejszona. – TheBasicMind

7

Podejrzewam, że przyczyna jest bardziej historyczna lub stylistyczna niż jakakolwiek inna. Tak właśnie zrobiły to frameworki NeXT, które stworzyły "styl" Cocoa. Jako korzyść z tego podejścia, sprawdzanie wartości w debugerze może dać znaczącą wartość (np. @ "CAGravityTop" lub coś podobnego zamiast bez znaczenia int). Ponieważ ciągi statyczne są obsługiwane w sposób inteligentny przez kompilator, porównanie może polegać na porównywaniu wskaźników, a nie na równości łańcuchów (patrz odpowiedź bbum), więc w tym podejściu występuje znikomy efekt wydajnościowy.

9

Wymienione typy nie mogą być rozszerzane bez dodawania dodatkowych wpisów w samym typie wyliczeniowym. W związku z tym niemożliwe jest posiadanie zawartości wyliczeniowej, które są traktowane zarówno jako formalny element wyliczonego typu, ale również nie są widoczne podczas normalnej kompilacji.

Weźmy na przykład CoreAnimation. Mogą istnieć wartości, które są używane wewnętrznie, które nie są obsługiwane lub udostępniane za pośrednictwem publicznego interfejsu API z różnych powodów; "szczegóły implementacji" natychmiast przychodzą na myśl.

Poza tym ciągi jako stałe umożliwiają rozszerzenie, jak sugeruje Eli. Podczas debugowania mają też znacznie więcej informacji. "kCAGravityTop" jest dużo bardziej orientacyjny niż, powiedzmy, "4".

Pod względem wydajności jest bardzo mało kar za używanie ciągów. Ciągi statyczne, z których składa się wewnętrzny odpowiednik każdej zewnętrznej deklaracji prawie każdej stałej ciągu, są obsługiwane efektywnie przez kompilator i -isEqualToString: pierwszym testem metody jest wskaźnik równości - bardzo szybki. Nie tak szybki jak przełącznik(), ale biorąc pod uwagę wielkość wykonywania kodu implikowanego przez stałą, różnica kilku cykli między przełącznikiem() i porównaniem łańcuchów jest nieistotna.

5

jeden powód myślałem na rzecz NSString jest to, że może on poprowadzony wokół gdziekolwiek id została zaakceptowana (takie jak userInfo lub jako klawisze słownikowe) natomiast prymitywne typy (teksty stałe) musiałby jakiś wrapper dla tego