Подтвердить что ты не робот

3 вопроса об использовании extern в проекте Objective-C

  • Когда я использую слово extern перед объявлением метода или переменной, могу ли я сделать его глобальным и, следовательно, читать/записывать/использовать для всего проекта?

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

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

спасибо

4b9b3361

Ответ 1

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

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

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

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

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

@interface MONClass : NSObject

extern const size_t MaximumThreads;

@end

имеет ту же область видимости (общедоступность) и видимость (public) как:

@interface MONClass : NSObject

@end

extern const size_t MaximumThreads;

поэтому нет смысла размещать связанные с классом C константы или функции в @[email protected] и @[email protected]. я рекомендую разместить их в том же заголовке, что и интерфейс, вне @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 в переводе С++, перевод С++ будет искать Something, объявленный как внешний символ С++. в objc нет никакой замены; objc является надмножеством C и наследует все C-функции. использование extern хорошо сформировано, и вы также можете найти его в рамках, которые вы используете (например, Foundation). они используют его, потому что им необходимо указать связь. objc не предлагает замену, по-видимому, потому, что она не требует замены или расширения.

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

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

MONExternC const size_t MONClassMaximumThreads;

Ответ 2

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

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

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

Ответ 3

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

Подробнее о различиях: "FOUNDATION_EXPORT" vs "extern"