Jaki jest najlepszy sposób tworzenia stałych w Objective-C

Tworzę klienta Reddita w celach edukacyjnych. Muszę mieć plik ze stałymi. Myślałem o zaimportowaniu pliku do pliku Reddit-Prefix.pch, aby stały były dostępne dla wszystkich plików. Czy to dobry sposób na robienie rzeczy? również, zrobiłem swoje badania i znalazłem kilka metod tworzenia stałych, ale nie wiem, który z nich użyć:

  • #define makro
  • const
  • static const
  • extern const
  • enum

Więc która droga jest preferowana? Co to jest konwencja? wiem ,że "to zależy", ale moje pytanie dokładniej brzmi: jakie są przypadki użycia dla każdego z tych rozwiązań?

Również, Jeśli używam extern const, Czy muszę importować plik, czy stałe będą dostępne globalnie bez importowania pliku?

Jedną z rzeczy, którą mógłbym logicznie wywnioskować jest to, że enum jest najlepszy wybór przy definiowaniu czegoś takiego jak niestandardowe domeny błędów (czy rzeczywiście mam rację?). A co z innymi?

Author: Robert Audi, 2013-06-21

2 answers

Pierwsze pytanie brzmi, jaki zakres chcesz, aby Twoje stałe miały, co tak naprawdę jest dwoma pytaniami:

  • czy te stałe są specyficzne dla jednej klasy, czy ma sens, aby mieć je w całej aplikacji?
  • jeśli są specyficzne dla danej klasy, czy są przeznaczone do użytku przez klientów danej klasy, czy tylko w obrębie tej klasy?

Jeśli są specyficzne i wewnętrzne dla jednej klasy, zadeklaruj je jako static const na górze .plik m, jak tak:

static NSString *const MyThingNotificationKey = @"MyThingNotificationKey";

Jeśli odnoszą się one do jednej klasy, ale powinny być publiczne/używane przez inne klasy, zadeklarować je jako extern w nagłówku i zdefiniować je w .m:

//.h
extern NSString *const MyThingNotificationKey;

//.m
NSString *const MyThingNotificationKey = @"MyThingNotificationKey";

Jeśli mają być globalne, zadeklaruj je w nagłówku i zdefiniuj w odpowiednim module, specjalnie dla tych stałych.

Możesz mieszać i dopasowywać je dla różnych stałych z różnymi poziomami tego, jak globalne mają być, oraz dla różnych stałych globalnych, które po prostu nie pasują do siebie-możesz je umieścić w osobne moduły, każdy z własnym nagłówkiem, jeśli chcesz.

Dlaczego nie #define?

Stara odpowiedź brzmi: "makra nie mają informacji o typie", ale Kompilatory są dziś dość mądre, jeśli chodzi o sprawdzanie liter (do których rozwijają się makra), a także zmiennych.

Nowoczesna odpowiedź jest taka, że debugger nie będzie wiedział o twoich makrach. Nie można powiedzieć [myThing addObserver:self forKey:MyThingNotificationKey] w poleceniu debuggera, Jeśli MyThingNotificationKey jest makrem; debugger może o nim wiedzieć tylko wtedy, gdy jest zmienna.

Dlaczego nie enum?

Cóż, rmaddy mnie uprzedził 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ć. (Jeszcze lepiej, Użyj makr NS_ENUM i NS_OPTIONS .) Dla innych rzeczy, musi używać czegoś innego; enum nie robi nic poza liczbami całkowitymi.

I inne pytania

Myślałem o zaimportowaniu pliku w prefiksie Reddit.plik pch, aby stały były dostępne dla wszystkich plików. Czy to dobry sposób na robienie rzeczy?

Prawdopodobnie nieszkodliwe, ale prawdopodobnie nadmierne. Importuj 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 dobry powód, aby używać tego dla stałych już nie.
  • const: najlepsze dla stałych lokalnych. Musisz również 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 specyficznych dla klas).
  • extern const: musisz tego użyć podczas eksportowania stałej w nagłówku.

Również, Jeśli używam extern const, Czy muszę importować plik, czy stałe będą dostępne globalnie bez importowania pliku?

Musisz zaimportować plik, albo w każdym pliku, w którym go używasz, lub w nagłówku prefiksu.

 372
Author: Peter Hosey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-22 09:09:22

FOUNDATION_EXPORT

Rozważ użycie FOUNDATION_EXPORT dla większej kompatybilności niż extern, ponieważ jest ono zdefiniowane w foundation i kompilowane do kompatybilnych formatów dla C, C++ i Win32.

Zgodnie z definicją w NSObjCRuntime.h

#if defined(__cplusplus)
#define FOUNDATION_EXTERN extern "C"
#else
#define FOUNDATION_EXTERN extern
#endif

#if TARGET_OS_WIN32

    #if defined(NSBUILDINGFOUNDATION)
        #define FOUNDATION_EXPORT FOUNDATION_EXTERN __declspec(dllexport)
    #else
        #define FOUNDATION_EXPORT FOUNDATION_EXTERN __declspec(dllimport)
    #endif

    #define FOUNDATION_IMPORT FOUNDATION_EXTERN __declspec(dllimport)

#else
    #define FOUNDATION_EXPORT  FOUNDATION_EXTERN
    #define FOUNDATION_IMPORT FOUNDATION_EXTERN
#endif
 8
Author: Steve Moser,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-14 19:46:38