24
  1. 当我在方法或变量声明之前使用该词extern时,我是否将其设为全局并因此在整个项目中可读/可写/可用?

  2. 如果我在关键字之前使用 extern,我的项目的一部分是否仍然无法访问它?例如,仅通过子类..例如当我使用“受保护”时。

  3. extern是 C 关键字,对吧?Objective-C 中是否有等价物?我实际上不明白他们为什么在 Objective-C 项目中使用 C 关键字。

谢谢

4

3 回答 3

39

1)您正在指定它的链接。外部链接允许您或任何客户引用该符号。

关于全局变量:如果变量是可变的和/或需要适当的构造,那么你应该考虑这个对象的方法或函数。值得注意的例外是 NSString 常量:

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

2)没有extern关键字影响可见性(公共/受保护/私有/包)的情况。要使用符号(例如常量或 C 函数),只需包含声明它的标头即可。

如果您是该语言的新手,会有些困惑:在两者之间放置 extern C 声明(常量、函数)@interface ... @end不会改变其范围:

@interface MONClass : NSObject

extern const size_t MaximumThreads;

@end

具有与以下相同的范围(全局)和可见性(公共):

@interface MONClass : NSObject

@end

extern const size_t MaximumThreads;

因此将与类相关的 C 常量或函数放在@interface...@endand中确实没有任何意义@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 中没有替换;objc 是 C 的超集,并继承了 C 的所有功能。使用的extern格式很好,您也可以在您使用的框架中找到它(例如 Foundation)。他们使用它是因为他们需要指定链接。objc 不提供替代品,大概是因为它不需要替换或扩展。

为避免这种情况,只需使用#define这样的:

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

MONExternC const size_t MONClassMaximumThreads;
于 2011-09-07T07:20:34.390 回答
17

extern并不意味着“全球”,它意味着“在其他地方定义”。它用于告诉编译器一个变量或函数存在(在另一个目标文件或库中),因此它不会抱怨它并且链接器将提供该目标文件或库。

结果extern意味着目标项目是全局的。

Objective-C 只是 C 的超集。C 中可用的所有内容在 Objective-C 中也可用,具有相同的语法和语义。在 Objective-C 中没有以另一种方式定义的 C 构造。

于 2011-09-07T07:21:34.917 回答
0

第 3 点:是的,您可以在目标 C 中使用 FOUNDATION_EXPORT,这是一个根据编译 C 或 C++ 解析为不同关键字的宏

有关差异的更多信息: “FOUNDATION_EXPORT”与“extern”

于 2016-01-06T05:42:32.453 回答