static const Vs extern const

ssh*_*h88 19 c static objective-c extern ios

我一直在我的头文件中使用静态const,如下所示:

static NSString * const myString = @"foo";
Run Code Online (Sandbox Code Playgroud)

但是已经读过这不是"安全"或正确的方法.显然,如果我想从另一个类访问我的const字符串,我应该在我的.h中声明字符串:

extern NSString * const myString;
Run Code Online (Sandbox Code Playgroud)

然后在我的.m文件中:

NSString * const myString = @"foo";
Run Code Online (Sandbox Code Playgroud)

它是否正确?如果是这样,是什么原因不直接在我的.h文件中将其声明为静态?它工作得很好,我看不到任何"安全"问题.它是一个const,因此它不能从外部改变,而是我故意需要在类之外访问它.我能想到的另一件事就是隐藏字符串的值?

Mar*_*n R 37

你的第一个变种

static NSString * const myString = @"foo"; // In .h file, included by multiple .m files
Run Code Online (Sandbox Code Playgroud)

myString每个"翻译单元"(粗略地说:在每个.m源文件中)本地定义一个包含头文件的变量.所有字符串对象都具有相同的内容"foo",但它可以是不同的对象,因此myString(每个单元中的指向字符串对象的指针)的值可能不同.

你的第二个变种

extern NSString * const myString; // In .h file, included by multiple .m files
NSString * const myString = @"foo"; // In one .m file only
Run Code Online (Sandbox Code Playgroud)

定义一个"全局"可见的单个变量myString.

示例:在一个类中,您发送带有myString用户对象的通知.在另一个类中,接收此通知并将用户对象与之进行比较myString.

在你的第一个变体中,必须进行比较,isEqualToString:因为发送和接收类可能有不同的指针(都指向NSString具有内容"foo" 的 对象).因此比较==可能会失败.

在您的第二个变体中,只有一个myString变量,因此您可以与之进行比较==.

因此,第二种变体在"共享字符串"是每个翻译单元中的相同对象的意义上更安全.