免费开源的iOS开发学习平台

OC变量Variable:2-全局变量extern

全局变量也称为外部变量,它不属于任何一个方法,而是属于一个源程序文件或者特定的类,根据其作用域来区分,全局变量包括内部全局变量以及外部全局变量,其中,内部全局变量的作用域是整个类,而外部全局变量的作用域是整个程序。定义全局变量时,变量名建议以小写字母g开头。

1、内部全局变量

如果在程序开始处(如:类定义的头部)定义变量,那么就可以在类中任何位置都可以使用这个变量的值,且变量的值是累计变化的。这个时候,这个变量的作用域在于整个类的实现文件,我们称之为内部全局变量。

例如,在MYClass.m文件中定义一个内部全局变量gNum,并且赋初始值0,那么就可以在该类的所有方法中使用该变量,不需要重新声明,并且对于该变量值的修改是累计的。

int gNum = 0;  //声明+定义

-(void)printGlobalVariable {
    NSLog(@"globalVar value: %d", gNum);
    gNum++;
}

在main()函数中,调用printGlobalVariable方法,来检验内部全局变量gNum的值是累加的。

int main(int argc, const char * argv[]) {
    @autoreleasepool {   
        MYClass *myClass = [[MYClass alloc] init];
        [myClass printGlobalVariable];
        [myClass printGlobalVariable];
        [myClass printGlobalVariable];
    }
    return 0;
}

运行结果:

2、外部全局变量(Global Variable)

内部全局变量,也是可以在程序的其他任何方法以及函数中访问的,这需要在访问内部全局变量的地方,声明变量类型以及名称(与定义时保持一致),并且添加extern关键字,即可访问该全局变量。

如下所示,我们可以定义一个新的类ClassA,在ClassA中的printExternVar方法中,首先声明全局变量,然后使用该全局变量。同时,我们可以再定义一个ClassB类,执行同样的操作。

  • ClassA.m文件中,声明全局变量gNum,变量名称与MYClass中定义的全局变量保持一致,并且添加extern关键字;
-(void)printExternVar{
    extern int gNum; //声明全局变量gNum
    NSLog(@"globalVar value (ClassA):%d",gNum);
    gNum++;
}
  • ClassB.m文件中,对全局变量gNum进行同样的声明;
-(void)printExternVar{
    extern int gNum; //声明全局变量gNum
    NSLog(@"globalVar value (ClassB):%d",gNum);
}
  • main.m文件中,调用MYClass类中定义的printGlobalVariable以及ClassA/ClassB中定义的printExternVar方法;
#import <Foundation/Foundation.h>
#import "MyClass.h"
#import "ClassA.h"
#import "ClassB.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {

        MyClass *myClass = [[MyClass alloc] init];
        
        [myClass printGlobalVariable];
        [myClass printGlobalVariable];
        [myClass printGlobalVariable];
        
        ClassA *classA = [[ClassA alloc] init];
        [classA printExternVar];
        
        ClassB *classB = [[ClassB alloc] init];
        [classB printExternVar];
        
    }
    return 0;
}

运行结果如下。我们可以看到,声明+定义在MYClass类中的全局变量gNum,在ClassA和ClassB中的值是累加的。

注意:需要区分变量的声明和定义,变量的声明不会引起内存空间的分配,而定义会分配内存空间。处理外部变量时,变量可以在很多地方声明为extern,但只能定义一次。如例子所示,gNum在ClassA和ClassB类中,分别进行了声明,但定义却是在MYClass类中完成的(gNum = 0)

示例代码

https://github.com/99ios/3.5.2