我经常在类实例方法中看到这样的代码片段:
static NSString *myString = @"This is a string.";
我似乎无法弄清楚为什么会这样。这仅仅是#define的objc等价于方法的范围吗?我(想)我理解变量的静态性质,但更具体地说是关于NSStrings,为什么它不被分配,init'd?
感谢〜
答案 0 :(得分:9)
我认为这个问题有两个不相关的部分。
一个是为什么它不被分配和初始化。答案是,当您编写@"foo"
表单的Objective-C字符串文字时,Objective-C编译器将为您创建一个NSString
实例。
另一个问题是static
修饰符的作用。它与在C函数中执行的操作相同,确保每次使用该方法时myString
变量都相同(即使在不同的对象实例之间)。
#define
宏是完全不同的:它是源代码的“编程剪切和粘贴”,在代码到达编译器之前执行。
答案 1 :(得分:4)
偶然发现了同样的static NSString
声明。我想知道这个静态魔法是如何工作的,所以我读了一下。我只会解决你问题的静态部分。
根据K&R,C中的每个变量都有两个基本属性:类型(例如float)和存储类(auto,register,static,extern,类型定义)。
静态存储类有两种不同的效果,具体取决于它是否使用:
块内的变量 没有声明它的存储类默认被认为是自动的(即它是本地的)。一旦块退出,它将被删除。当您将自动变量声明为静态时,它将在退出时保持其值。当再次调用代码块时,该值仍然存在。
全局变量(在与函数相同的级别声明)始终是静态的。明确声明全局变量(或函数)为 static 会将其范围限制为单个源代码文件。它无法访问,并且不会与其他源文件发生冲突。这称为内部链接。
如果您想了解更多内容,请阅读internal and external linkage in C。
答案 2 :(得分:2)
您没有看到对alloc
/ init
的调用,因为@"..."
构造在内存中创建了一个常量字符串(通过编译器)。 / p>
在此上下文中,static
表示无法从定义变量的文件中访问该变量。
答案 3 :(得分:1)
对于NSString alloc的部分,init:
我认为首先,它可以被认为是一种方便,但对于[[NSString alloc] init]它并不是一样的。
我在这里找到了一个有用的链接。你可以看一下 NSString and shortcuts
对于static和#define:
的部分类中的静态实例意味着您可以使用该类的任何实例进行访问。您可以更改静态值。对于函数,它意味着在函数调用
之间保留变量的值#define是你放置一个宏常量来避免幻数和字符串并定义函数宏。 #define MAX_NUMBER 100.然后你可以使用int [MAX_MUMBER]。编译代码时,它将被复制并粘贴到int [100]
中答案 4 :(得分:1)
这是NSString的特殊情况初始化案例,它简单地将NSString指针指向在启动时分配和引入的实例(或者可能是懒惰,我不确定。)以这种方式创建了这些NSString实例中的一个您在程序中使用的每个唯一@“”。
即使你不使用static关键字,我也认为这是真的。此外,我认为使用此字符串初始化的所有其他NSStrings将指向同一个实例(不是问题,因为它们是不可变的。)
它与#define不同,因为你实际上有一个NSString变量,通过使用= @“whatever”初始化创建字符串。它似乎更像是c const char* somestr = "blah blah blah"
。