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联合使用。
先到这吧,有后续资料再补充。。。
extern引发的闹剧的更多相关文章
- (转)函数调用方式与extern "C"
原文:http://patmusing.blog.163.com/blog/static/13583496020103233446784/ (VC编译器下) 1. CALLBACK,WINAPI和AF ...
- 在头文件声明全局变量和创建extern
在头文件声明全局变量和创建extern 问题: 是否有简单的方法,在头文件里定义我的变量,同时也为它们创建extern定义? 回答: 是的.尽管这不是必需的,使用正确的宏和一个头文件还是很容易实现的. ...
- 关于extern的用法
extern表示该变量或者函数时在另一个地方定义了. 在C++编程中,如果将程序分为多个文件,则需要有在文件间共享代码的方法,这时如果一个变量或者函数需要在多个文件中使用,则可以使用extern来声明 ...
- extern的使用详解(多文件编程)——C语言
extern——关键字 extern是C语言中的一个关键字,一般用在变量名前或函数名前,作用是用来说明“此变量/函数是在别处定义的,要在此处引用”,extern这个关键字大部分读者应该是在变量的存储类 ...
- 一个由正则表达式引发的血案 vs2017使用rdlc实现批量打印 vs2017使用rdlc [asp.net core 源码分析] 01 - Session SignalR sql for xml path用法 MemCahe C# 操作Excel图形——绘制、读取、隐藏、删除图形 IOC,DIP,DI,IoC容器
1. 血案由来 近期我在为Lazada卖家中心做一个自助注册的项目,其中的shop name校验规则较为复杂,要求:1. 英文字母大小写2. 数字3. 越南文4. 一些特殊字符,如“&”,“- ...
- 【C#】无损转换Image为Icon 【C#】组件发布:MessageTip,轻快型消息提示窗 【C#】给无窗口的进程发送消息 【手记】WebBrowser响应页面中的blank开新窗口及window.close关闭本窗体 【手记】调用Process.EnterDebugMode引发异常:并非所有引用的特权或组都分配给呼叫方 【C#】DataRowState演变备忘
[C#]无损转换Image为Icon 如题,市面上常见的方法是: var handle = bmp.GetHicon(); //得到图标句柄 return Icon.FromHandle(handle ...
- const,static,extern 简介
const,static,extern 简介 一.const与宏的区别: const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量. 执行时刻:宏是预编 ...
- [WCF]缺少一行代码引发的血案
这是今天作项目支持的发现的一个关于WCF的问题,虽然最终我只是添加了一行代码就解决了这个问题,但是整个纠错过程是痛苦的,甚至最终发现这个问题都具有偶然性.具体来说,这是一个关于如何自动为服务接口(契约 ...
- dubbox微服务实例及引发的“血案”
Dubbo 是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成. 主要核心部件: Remoting: 网络通信框架 ...
随机推荐
- App的启动过程
App的启动过程 所有的app都是通过launcher去启动的 launcher自己也是一个app,一个系统级别的app,放在asystem/app/下,使用系统签名. 对代码进行分析
- 扒一扒自从买了kindle后看的书
一.<性别战争> 讲述的是动物界各类动物的xxx(你懂的),以动物拟人化的口吻来进行问答,十分的生动形象,虽说和自己的生活没有多大联系,但是偶尔了解一下,也是意外的不错的感觉. 二.< ...
- Spring的xml文件配置方式实现AOP
配置文件与注解方式的有很大不同,多了很多配置项. beans2.xml <?xml version="1.0" encoding="UTF-8"?> ...
- PHP curl 实现RESTful PUT DELETE 实例
PHP curl 实现RESTful PUT DELETE 实例 客户端 client.php <?php //PUT $curl_handle = curl_init ();// Set de ...
- 把excel导入的自定义时间改成yyyyMMdd
public static String changeCellToString(XSSFCell cell){ String result = "";// Object value ...
- spark快速大数据分析学习笔记*初始化sparkcontext(一)
初始化SparkContext 1// 在java中初始化spark import org.apache.spark.SparkConf; import org.apache.spark.api.ja ...
- ngui中 代码调用按钮事件(后来改成了按钮绑定键盘..)
ngui中 代码调用按钮事件 好烦人啊这个问题, 我弄完发上来 这个问题解决了一半 发现可以用 按钮绑定来解决这个问题,并且更安全方便快速 直接在按钮上添加一个 key binding 指定按键 搞定 ...
- pc端页面在移动端显示问题
1.pc端页面在移动端显示,默认视口宽度是980px(也就是body宽度是980px),可通过meta标签设置为需要的尺寸,比如页面中元素最大宽度是1220px,则如下所示 <meta name ...
- Android编译环境折腾记
题记:感觉是时候写点什么了=_=! 第一次安装了ubuntu14.04.5,官网下载的iso,官网下的jar,编译android4.x需要安装jdk6,更高的版本会有问题,baidu到很多搭建环境的步 ...
- comparator接口与compare方法的实现
刷leetcodecode时看到一道题需要利用自定义的比较器进行排序,最开始一头雾水,看了API终于懂了~ Arrays.sort(T[] a,Comparator<? super T> ...