3 вопроса об extern, используемых в проекте Objective-C - PullRequest
24 голосов
/ 07 сентября 2011
  1. Когда я использую слово extern перед объявлением метода или переменной, я делаю его глобальным и, следовательно, доступным для чтения / записи / использования для всего проекта?

  2. Если я использую extern перед ключевым словом, есть ли вероятность, что оно все еще недоступно для части моего проекта?Например, только по подклассам .. например, когда я использую «защищенный».

  3. extern - это ключевое слово C, верно?Есть ли эквивалент в Objective-C?Я на самом деле не понимаю, почему они используют ключевое слово C в проекте Objective-C.

спасибо

Ответы [ 3 ]

39 голосов
/ 07 сентября 2011

1) вы указываете его связь.extern linkage позволяет вам или любому клиенту ссылаться на символ.

в отношении глобальных переменных: если переменная изменчива и / или нуждается в правильном построении, вам следует рассмотреть методы или функции для этого объекта.заметным исключением из этого являются константы NSString:

// MONClass.h
extern NSString* const MONClassDidCompleteRenderNotification;
// MONClass.m
NSString* const MONClassDidCompleteRenderNotification = @"MONClassDidCompleteRenderNotification";

2) не существует случая, когда ключевое слово extern влияет на видимость (public / protected / private / package).чтобы использовать символ (например, константу или функцию C), просто включите заголовок, в котором он объявлен.

несколько сбивает с толку, если вы новичок в языке: размещение внешних объявлений C (констант, функций) между @interface ... @end не изменит свою область видимости:

@interface MONClass : NSObject

extern const size_t MaximumThreads;

@end

имеет ту же область видимости (глобальную) и видимость (общедоступную), что и:

@interface MONClass : NSObject

@end

extern const size_t MaximumThreads;

, поэтому действительно нет смысла размещать ваш класссвязанные константы C или функции в @interface...@end и @implementation...@end.я рекомендую поместить их в тот же заголовок, что и интерфейс, за пределами @interface/@end и @implementation/@end и добавить к имени префикс с классом, с которым он связан, например:

@interface MONClass : NSObject

@end

extern const size_t MONClassMaximumThreads;
// MONClass.m
const size_t MONClassMaximumThreads = 23;

и если вы хотите эту константучтобы быть приватным, просто объявите и определите это так:

// MONClass.m
static const size_t MONClassMaximumThreads = 23;

@implementation MONClass

@end

к сожалению, не существует столь же простого или распространенного способа сделать эту константу защищенной с помощью objc.

наконец, вы также можетеиспользуйте методы класса, если число должно варьироваться в зависимости от класса:

@interface MONMammal : NSObject
+ (NSUInteger)numberOfLegs;
@end

@implementation MONDog
+ (NSUInteger)numberOfLegs { return 4; }
@end
@implementation MONHuman
+ (NSUInteger)numberOfLegs { return 2; }
@end

3) да, среди других языков.например, если вы используете extern const int Something в переводе c ++, перевод c ++ будет искать Something, объявленный как внешний символ C ++.в объекте нет замены;objc является надмножеством C и наследует все функциональные возможности C.использование extern правильно сформировано, и вы также можете найти его в используемых вами средах (например, Foundation).они используют его, потому что им нужно указать связь.objc не предлагает замену, предположительно потому, что для этого не требуется замена или расширение.

, чтобы избежать этого, просто используйте #define, например:

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

MONExternC const size_t MONClassMaximumThreads;
17 голосов
/ 07 сентября 2011

extern не означает «глобальный», он означает «определенный в другом месте».Он используется, чтобы сообщить компилятору, что переменная или функция существует (в другом объектном файле или библиотеке), чтобы он не жаловался на это и что компоновщик будет обеспечен этим объектным файлом или библиотекой.

Как следствие, extern подразумевает, что целевой элемент является глобальным.

Objective-C - это просто расширенный набор C. Все, что доступно в C, доступно и в Objective-C, с тем же синтаксисом исемантический.Не существует конструкции C, которая определена по-другому в Objective-C.

0 голосов
/ 06 января 2016

Пункт 3: Да, вы можете использовать FOUNDATION_EXPORT в задаче C, которая представляет собой макрос, который разрешается в другое ключевое слово в зависимости от компиляции C или C ++

Подробнее о различиях здесь: "FOUNDATION_EXPORT" против "Экстерн "

...