关于Objective-C项目中使用的extern的3个问题
-
当我在方法或变量声明之前使用
extern
一词时,我是否将其设置为全局,因此在整个项目中可读/可写/可用? -
如果我在关键字之前使用extern,那么我的项目的一部分仍然无法访问它吗? 例如,仅由子类…例如当我使用“protected”时。
-
extern
是一个C关键字,对吧? Objective-C中是否有等价物? 我实际上不明白为什么他们在Objective-C项目中使用C关键字。
谢谢
1)你正在指定它的联系。 extern链接允许您或任何客户端引用该符号。
关于全局变量:如果变量是可变的和/或需要适当的构造,那么您应该考虑该对象的方法或函数。 值得注意的例外是NSString常量:
// MONClass.h extern NSString* const MONClassDidCompleteRenderNotification; // MONClass.m NSString* const MONClassDidCompleteRenderNotification = @"MONClassDidCompleteRenderNotification";
2)extern关键字不会影响可见性(public / protected / private / package)。 要使用符号(例如常量或C函数),只需包含声明它的头。
如果你是这个语言的新手,有点混乱:在@interface ... @end
之间放置extern 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)是的,还有其他语言。 例如,如果你在c ++翻译中使用extern const int Something
,那么c ++翻译将查找声明为extern C ++符号的Something
。 objc中没有替代品; objc是C的超集,并且inheritance了C的所有function。 extern
使用很好,您也可以在您使用的框架中找到它(例如Foundation)。 他们使用它是因为他们需要指定链接。 objc不提供替代品,大概是因为它不需要更换或延期。
要避免这种情况,只需使用#define
如下所示:
#if !defined(__cplusplus) #define MONExternC extern #else #define MONExternC extern "C" #endif MONExternC const size_t MONClassMaximumThreads;
extern
并不意味着“全球”,它意味着“在别处定义”。 它用于告诉编译器存在变量或函数(在另一个目标文件或库中),因此它不应该抱怨它,并且链接器将提供该对象文件或库。
因此, extern
意味着目标项是全局的。
Objective-C只是C的超集.C中可用的所有东西都可以在Objective-C中使用,具有相同的语法和语义。 在Objective-C中没有以另一种方式定义的C构造。
第3点:是的,您可以在目标C中使用FOUNDATION_EXPORT,它是一个宏,根据编译C或C ++解析为不同的关键字
有关差异的更多信息: “FOUNDATION_EXPORT”vs“extern”