extern引发的闹剧
最近一个朋友让我帮他解决一个问题,由于源代码不方便贴出来,所以就自己写了个demo把问题重现一次
1、新建一个application,添加一个继承于NSObject的类
本来是随便写的,就将此类命名为Object,会出现在控制台输出一段文字如下
Class Object is implemented in both /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/lib/libobjc.A.dylib and /Users/groupfly/Library/Developer/CoreSimulator/Devices/1B7CAB3E-6F13-49EC-B5F7-96CB62C1D5A6/data/Containers/Bundle/Application/60D48F1B-E49D-4D2D-AAD7-A72984CF8CB7/extern.app/extern. One of the two will be used. Which one is undefined.
没有仔细查阅资料,大概意思应该是 libobjc.A.dylib这个库里面也有一个已经实现了的Object,两者重复导致的,属于运行时问题(编译起来没问题,无论有没有在其他文件中使用,运行之后都会出现这段文字)
然后把类型改为NObject
.m文件如下:
#import "NObject.h"
extern int mtu;
@interface NObject ()
@end
@implementation NObject
+ (void)test{
mtu = 1; // 一般来说全局变量在声明的文件中,不会实现
}
@end
2、很多开发者应该都知道,extern是用来声明全局变量的,一般在声明文件中,不会被实现,但是从朋友发出来的代码是公司供应商提供的demo,主要文件中使用到了这个extern关键字,并且在此文件中对该变量多次操作。问题即将出现,当你将此文件导入到自己的项目中时,即
#import "ViewController.h"
#import "NObject.h" // 无论有没有导入此文件 都会报错(此文件中声明了全局变量,并且也同时对他进行了操作(复制等))
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {}
@end
这时就会报错如下图:
这个报错是不是有点类似于导入第三方库时可能会出现的现象
3、解决方法:在使用导入后的文件时,引入该全局变量即可:
#import "ViewController.h"
#import "NObject.h"
int mtu ;
@interface ViewController ()
@end
@implementation ViewController...
这样即可解决报错
4、查阅资料:
extern作用: 只是用来获取全局变量(包括全局静态变量)的值,不能用于定义变量
extern工作原理:先在当前文件查找有没有全局变量,没有找到,才会去其他文件查找。
// 全局变量:只有一份内存,所有文件共享,与extern联合使用。
先到这吧,有后续资料再补充。。。