美文网首页
2018-01-25

2018-01-25

作者: 木冬凉 | 来源:发表于2019-03-14 15:21 被阅读0次

Static修饰局部变量:

当static关键字修饰局部变量时,只会初始化一次。

例 1:

@implementationViewController- (void)viewDidLoad {    [superviewDidLoad];self.view.backgroundColor = [UIColorwhiteColor];    [selftest];}- (void)didReceiveMemoryWarning {    [superdidReceiveMemoryWarning];// Dispose of any resources that can be recreated.}- (void)viewWillAppear:(BOOL)animated {    [superviewWillAppear:animated];NSLog(@"---------- viewWillAppear -------------");    [selftest];}- (void)viewDidAppear:(BOOL)animated {    [superviewDidAppear:animated];NSLog(@"---------- viewDidAppear -------------");    [selftest];}- (void)test {NSIntegeri =0;    i++;staticNSIntegerstaticValue =0;    staticValue++;NSLog(@"i = %ld, s.value = %ld", (long)i, (long)staticValue);}@end

打印结果:

1535336913623.jpg

当static关键字修饰局部变量时,在程序中只有一份内存。

例 2:

@implementationViewController- (void)viewDidLoad {    [superviewDidLoad];self.view.backgroundColor = [UIColorwhiteColor];    [selftest];}- (void)didReceiveMemoryWarning {    [superdidReceiveMemoryWarning];// Dispose of any resources that can be recreated.}- (void)viewWillAppear:(BOOL)animated {    [superviewWillAppear:animated];NSLog(@"---------- viewWillAppear -------------");    [selftest];}- (void)viewDidAppear:(BOOL)animated {    [superviewDidAppear:animated];NSLog(@"---------- viewDidAppear -------------");    [selftest];}- (void)test {NSString*normalString;staticNSString*staticString;NSLog(@"normal = %p, static = %p", &normalString, &staticString);}@end

打印结果:

1535336222431.jpg

从打印结果可以看出,Static修饰的局部变量在程序中只有一份内存(如图结果:0x104358ef8)。

Static关键字不可以改变局部变量的作用域。

例 3:

1535338718265.jpg

如图中所示,我在test方法中定义了一个static修饰的局部变量staticValue,如果想在其他方法中直接使用这个变量则会报错:变量未声明,所以可以得出结论:Static关键字修饰的局部变量只限制在当前作用域范围内使用(即不可改变其作用域)。

Static关键字可延长局部变量的生命周期。

这个观点我们还是借助例1的代码来说明。在例1中我们定义了一个普通局部变量i和一个static修饰的局部变量staticValue,分别让他们自增1,然后输出结果,在打印结果中我们看到普通局部变量的值永远是1(每当调用一次函数,就会定义一个新的变量每次i的值都是零,自增后就是1),而static修饰的局部变量的值会一直增长(被static修饰的变量只会初始化一次,永远都只有一份内存),我们可以得出Static关键字可延长局部变量的生命周期,直到程序结束才销毁

Static修饰全局变量:

当static关键字修饰全局变量时,作用域仅限于当前文件,外部类是不可以访问到该全局变量的。

默认情况下,全局变量在整个程序中是可以被访问的(即全局变量的作用域是整个项目文件)

#import"SLStaticDemo.h"NSIntegerage;@implementationSLStaticDemo@end

#import"ViewController.h"NSIntegerage;@interfaceViewController()@end@implementationViewController- (void)viewDidLoad {    [superviewDidLoad];self.view.backgroundColor = [UIColorwhiteColor];        age =20;NSLog(@"age = %ld", (long)age);}

在工程SLStaticDemo.m文件中声明一个全局变量NSInteger age;,同时在ViewController.m文件中声明一个全局变量NSInteger age;,然后编译会报错:

1535349477718.jpg

通过错误信息我们可以知道全局变量age重复声明,所以可以验证全局变量的作用域是整个项目文件

要解决这个错误信息,我们可以在全局变量前面添加static关键字,把全局变量的作用域缩小到当前文件,保证外部类无法访问(即使在外部使用extern关键字也无法访问)。

#import"SLStaticDemo.h"staticNSIntegerage;@implementationSLStaticDemo@end

Extern关键字

在上面我们提到extern关键字,那这个关键字的作用是什么呢?我们还是用上面的代码来理解extern关键字的作用(注意:代码中全局变量的定义NSInteger age = 10;并没有static)。

#import"SLStaticDemo.h"NSIntegerage =10;@implementationSLStaticDemo@end

#import"ViewController.h"@interfaceViewController()@end@implementationViewController- (void)viewDidLoad {    [superviewDidLoad];self.view.backgroundColor = [UIColorwhiteColor];externNSIntegerage;NSLog(@"age = %ld", (long)age);        age +=10;NSLog(@"age = %ld", (long)age);}- (void)didReceiveMemoryWarning {    [superdidReceiveMemoryWarning];// Dispose of any resources that can be recreated.}@end

打印结果:

1535351089734.jpg

从输出结果age = 10我们可以看到即便我们在ViewController.m中并没有importSLStaticDemo.h也能得到SLStaticDemo中定义的age变量,这就是extern关键字的功劳(extern可以访问全局变量);

如果不想让外部类访问全局变量,则可以在定义全局变量时加上static关键字。

总结:

static关键字修饰局部变量:

当static关键字修饰局部变量时,只会初始化一次且在程序中只有一份内存;

关键字static不可以改变局部变量的作用域,但可延长局部变量的生命周期(直到程序结束才销毁)。

static关键字修饰全局变量:

当static关键字修饰全局变量时,作用域仅限于当前文件,外部类是不可以访问到该全局变量的(即使在外部使用extern关键字也无法访问)。

extern关键字:

想要访问全局变量可以使用extern关键字(全局变量定义不能有static修饰)。

全局变量是不安全的,因为它可能会被外部修改,所以在定义全局变量时推荐使用static关键字修饰。

作者:WSonglin

链接:https://www.jianshu.com/p/9c09989b6862

来源:简书

简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

相关文章

网友评论

      本文标题:2018-01-25

      本文链接:https://www.haomeiwen.com/subject/oexbaxtx.html