Ответ 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;