2013-07-16 44 views
14

Zgaduję, że użyłbym tylko UIKIT_EXTERN, jeśli istnieje szansa na kod C++ w moim projekcie, który może korzystać ze zmiennej.Kiedy używać UIKIT_EXTERN kontra tylko extern

Jeśli tak jest, czy nie byłoby po prostu bezpiecznie ogłaszać wszystkie dostępne z zewnątrz stałe za pomocą UIKIT_EXTERN?

Dlaczego nie widzę tego więcej?

+0

Inną opcją jest "FOUNDATION_EXPORT" na http://stackoverflow.com/questions/10953221/foundation-export-vs-extern –

Odpowiedz

22

Zgaduję, że użyłbym tylko UIKIT_EXTERN, jeśli istnieje szansa na kod C++ w moim projekcie, który może używać tej zmiennej.

Dobrze. To jest główny powód. Dzieje się tak, ponieważ symbole C i C++ używają różnych konwencji nazewnictwa.

Istnieje mniej powszechny powód: UIKIT_EXTERN określa również domyślną widoczność.

Uwaga: Bardziej ogólnie, "symbol" - nie "zmienny" od extern może również być stosowany do stałych, funkcji itd.

Jeśli tak, to czy nie byłoby po prostu bezpiecznie ogłosić wszystkie dostępne z zewnątrz stałe za pomocą UIKIT_EXTERN?

Krótka odpowiedź: Byłoby dobrą praktykę (czytaj: „bezpieczny”), aby korzystać z tej formy, ale jest to zwykle najlepsze dla biblioteki zadeklarować swój odpowiednik UIKIT_EXTERN.


UIKIT_EXTERN jest deklaracją UIKit. Biblioteki nie powinny zależeć od tej deklaracji i po prostu zdefiniować swój własny synonim - i wiele z nich, ale uważam, że jest bardziej powszechne w C i C++, ponieważ te programy często są kierowane na więcej platform i duży procent programów iOS nie jest rozwinięty do obsługi innych platform. W przeciwnym razie, programy Objective-C, które nie wymagają UIKit, mogą zależeć od UIKit z powodu tej deklaracji, więc będą musiały zaimportować UIKit (tak, że deklaracja UIKIT_EXTERN jest widoczna).

Co więcej, UIKit nie jest dostępny na wszystkich platformach, na których można uruchamiać programy na iOS (tzn. Może to być C, C++ lub zależą od Fundacji i przenośny dla OS X). Więc nawet jeśli ktoś (z ciekawością) upierał się przy deklarowaniu własnego, był złym pomysłem, wybór CF_EXPORT (odpowiednik CoreFoundation) byłby bardziej przenośną opcją, ponieważ mógłby być również użyty dla C, C++ i na OS X. Ponadto twoja biblioteka byłaby tylko musi zawierać CoreFoundation (co najmniej).

Jeśli twoja biblioteka zależy od UIKit, a biblioteki muszą zostać zaimportowane przez twoją bibliotekę, jest bardzo mało prawdopodobne, że użycie ich synonimu spowoduje problem dla twojej biblioteki.

Ale jest to całkiem spory zbiór warunków - Biblioteczka jest bardzo łatwa do zadeklarowania:. Krótko mówiąc, dobrze napisana i przenośna biblioteka powinna (prawie) nigdy nie używać "surowego" extern, a zbędne biblioteki nie powinny być dobrą rzeczą (w tym przypadku UIKit).

To byłby zły projekt wybór do korzystania UIKIT_EXTERNchyba biblioteki były nierozłączne od UIKit - takich jak zbiór UIView podklasy.

Jeśli twoja biblioteka zajmuje się tylko typami Fundacji, importowanie UIKit oznacza, że ​​twoja biblioteka będzie (niepotrzebnie) nieużyteczna w systemie OS X (do czasu usunięcia tego importu UIKit).

Osoby, które nie mają dużego doświadczenia w korzystaniu z C++ z C (w tym z supersetami) mogą nie wiedzieć, że nazwy symboli są różne, więc mogą po prostu użyć extern bezpośrednio. W końcu niektóre programy nie zostały początkowo zaprojektowane do użycia poza tłumaczeniami C i/lub Objective-C, więc mogły po prostu użyć extern bez warunkowej dekoracji do tłumaczenia.

Wreszcie UIKIT_EXTERN nie może zrobić dokładnie to, czego można oczekiwać/chcesz ponieważ określa:

  • extern C symbol
  • który ma domyślną widoczność

Dla symboli bibliotecznych widocznych tłumaczeń ObjC , to jest doskonałe.

+2

Wow, świetna odpowiedź. Dziękuję Ci. –

+0

@BenCoffman nie ma za co. + Dzięki – justin

1

Przede wszystkim należy uczynić klasę widoczną poza bieżącą biblioteką/plikiem wykonywalnym. Prawdopodobnie nie będziesz jej potrzebował, chyba że tworzysz biblioteki.

Jak podkreślasz, główną zaletą korzystania z makra jest to, że jest wbudowany w dodatkową ochronę C++ extern, więc jeśli rzeczywiście tworzysz bibliotekę, jest to zdecydowanie dobry pomysł (w przeciwnym razie rozmówca musi być świadomy i dodaj deklarację extern C).

to jest opisane w dokumentacji ADC tutaj:

i jest dość dobrze tutaj odpowiedzi: