静态变量和全局变量的区别

Difference between static and global variables

下面的代码有什么区别?

@implementation MyClass

static int myVar =0;
int _myVar =0;

我为 MyClass 的不同对象获得了相同的值,并且两者都对 MyClass 的所有方法可见...

static 限制变量的范围。在您的情况下,变量将在 MyClass 文件中可见。

但是,没有static的变量声明意味着变量默认是自动。这意味着您的 static 将贯穿所有方法调用,并且 automatic 将在您调用方法时分配,然后在某个时候释放。

静态变量和全局变量在生命周期和作用域的行为上有很大不同。首先,让我区分生命和范围。一个对象的生命周期决定了这个对象是否还在(进程的)内存中,而对象的作用域就是在这个位置我是否可以通过它的名字知道这个变量。对象可能是活动的,但不可见(不在范围内)但不是该对象不活动但在范围内(除了通过指针引用对象的动态分配对象)。

静态变量在定义它们的模块范围内是局部的,但生命贯穿整个程序。说一个函数内部的静态变量不能从函数外部调用(因为它不在范围内)但是它是活动的并且存在于内存中。下次进入此函数(在同一程序中)时,将访问相同的内存块,现在保留变量旧值,并且这次不会像函数中的其他变量(自动变量)一样为该变量分配新内存。所以基本上这个变量在整个程序中都存在。类似地,如果在全局 space 中定义了一个静态变量(比如在文件开头),那么这个变量将是 只能在此文件(文件范围)中访问。

另一方面,全局变量必须在全局范围内定义,在整个程序中持续存在(life is),作用域也在整个程序中。这意味着可以从任何函数、程序的任何文件访问此类变量。

所以如果你有一个全局变量并且你将你的文件作为一个库分发并且你不希望其他人访问你的全局变量,你可以通过在关键字 static 前加上前缀使其成为静态的(当然如果不需要相同的变量在你的其他文件中)。

这些变量都不与 MyClass 相关,而且都是全局变量,这就是为什么您在 MyClass 的所有实例中看到相同的值。如果你想让 _myVar 成为一个实例变量,那么它需要放在方括号之间:

@implementation MyClass {
    int _myVar;
}
...
@end

代码中变量之间的区别在于 static 变量不能在实现文件(我假设称为 MyClass.m)范围之外访问,而非 static 一个可以从应用程序的任何地方访问,但是您需要让编译器对任何想要访问它的代码中的 extern int _myVar; 感到满意;这通常是通过将 extern 声明放在头文件中来完成的。