iOS全局变量的有趣的事

 

在开发过程中,您可能经常会遇到"duplicate symbol _xxx"的错误,大多都是变量重复,您可能需要给某一个类的变量改名字,为什么会出现类似的问题呢,我做了个试验,发现了很有意思的事情。

试验一

case1

A.h声明

extern NSString *  kAppErrorDomain

A.m实现

NSString *  kAppErrorDomain = @"这是在A文件声明的变量"

b.h声明

extern NSString *  kAppErrorDomain

b.m实现

NSString *  kAppErrorDomain ;//没有赋值

这时候你会发现,咦?我虽然在两个文件声明的同样的变量,但是并没有冲突,且可以正常运营,并且我可以很负责的告诉你,这两个kAppErrorDomain变量的地址都是同一个地址。

case2

b.m实现换一下

NSString *  kAppErrorDomain = @"这是在B文件声明的变量"

运行报错,"duplicate symbol _kAppErrorDomain in:",我们想要的错误出来了。这就很正常了,你确实声明了相同的变量。

有同学说了,我之前定义过相同的变量,没问题啊。那ok,我们看一下没问题的相同变量是什么样的。

试验二

case1

a.h声明

 extern NSString * const kAppErrorDomain;

a.m实现

NSString * const kAppErrorDomain = @"这是在A文件声明的变量"

b.h声明

 extern NSString * const kAppErrorDomain;

b.m实现

NSString * const kAppErrorDomain = @"这是在B文件声明的变量"

运行成功,且使用没问题。为什么呢?我还没弄明白,但我可以只用一句代码让本可以运行成功的程序出错。

在a或b的.m增加

 NSLog(@"%p",&kAppErrorDomain);

再编译试试,出错,"duplicate symbol _kAppErrorDomain in:",好玩么,就想看个地址,苹果不给看。那怎么解决这种问题?

实验三

case1

a.h声明修改

 static NSString * const kAppErrorDomain;

a.m实现修改

static NSString * const kAppErrorDomain = @"这是在A文件声明的变量"

b.h声明修改

 static NSString * const kAppErrorDomain;

b.m实现修改

static NSString * const kAppErrorDomain = @"这是在B文件声明的变量"

"这下大家满意了吧",也能打印值了,也能打印地址了,但你会发现,相同的变量具有不同的地址,因为static的作用域与他定义的位置相关,定义在文件就只在文件内有效,定义在方法内,就只在方法内有效。所以其实a与b各自存在一个kAppErrorDomain变量,其实他俩并不是公用一个。

case2

a.h,a.m不变,

把b.h修改为

#import "a.h"

b.m删除实现

运行程序,效果同样,相同的变量,不同的地址。这说明了#import一个有意思的地方,它其实是对import的文件做copy操作,这也就是为什么建议在.h文件尽量的少用#import,而是用@class。

 

ok,结束。

你可能感兴趣的:(iOS全局变量的有趣的事)