iOS OC 学习手册iOS Developer

从在.h头文件中赋值并初始化static变量谈谈预编译和链接

2017-12-27  本文已影响147人  逐逐逐

写这篇文章的原因:

之前组里一个队友在写OC的时候,在OC的.h头文件里初始化并赋值了一个静态的字符串变量,并在多个.m实现文件引入了这个头文件然后使用了这个静态成员变量(虽然这种做法不提倡),导致程序出现了一些奇奇怪怪的行为(每个.m文件中的静态变量都不一样),他找了很久也百思不得解。这里我就针对这个问题谈谈预编译过程,以及浅谈相关的编译和链接的一些知识,希望对大家有帮助,也欢迎大神吐槽拍砖:

文章结构图.png 在.h中添加静态变量的情况如下:
s1.png
那我们开始,首先普及一下概念
静态变量:

-----首先普及一下加上 static 关键字的静态变量的特性:OC 是基于 C 语言的,在C语言中一个变量加上 static 关键字代表这个变量是只能在当前文件内使用的,并且在当前文件内同名的静态成员变量只能有一个,如果有多个那么后初始化并赋值的静态变量会把之前同名的覆盖。

预编译:

然后简单讲讲预编译:预编译就是在编译之前由IDE(对我们来说就是XCODE)对文件进行的一些处理,其中包括:1.宏替换(#define); 2.文件包含(#import) ;和 3.条件编译(#if #endif); 三项。这里只介绍概念,后文会细说。当然这个阶段还会对我们写的注释进行处理比如 #pragma 。通俗的说预编译就是对带 “井” 前缀(#***)的部分进行处理和简单的替换操作。那么以下我就针对开头我说的,在头文件中引入静态变量问题开始讲:

1.首先讲讲本次测试用的类的结构和方法,如下图:

ContainStringClass.h

这是 ContainStringClass 类的.m实现文件

ContainStringClass.m

然后是 ViewController 的 ViewDidLoad() 方法中的代码,目的是为了测试和打印

viewController.png

2.下面讲讲以上两个类的作用:

以上测试用的两个类。代码的功能就是:

打印结果

怕大家看不清附上打印结果放大版

打印结果放大版.png

3.下面解释一下输出结果

可以看到,虽然在 ViewController.m 中和 ContainStringClass.m 里边访问 “同一个” 在 ContainStringClass.h 中声明的静态变量,可是它们的值是互不影响的,仅在最初他们的值一样都是 staticString 的初值 @“origin” 。
在 ViewController.m 中对静态变量 staticString 的修改仅在 ViewController.m 中有效;同样的,在 ContainStringClass.m 中的修改仅在 ContainStringClass.m 中有效;

为什么呢?下面我们来说明:

4.下面我们再来讲讲预编译:

5.然后我们谈谈编译:

6.然后是链接:

7.链接之后的就是可执行程序了

main函数

8.拓展:

根据以上知识知道预编译的意思了吧,那么如果:

s10.png

最后:

如果修改链接器参数是可以容忍多个未赋值的全局变量的(但是别这么干,因为每次用具体用哪个就不知道了,估计为了安全现在主流IDE都是不允许任何形式的多个全局变量);
如果对计算机和执行过程感兴趣推荐大家看看 《深入理解计算机系统》这本书,有点难,内容也有点多但是写的很好。有兴趣希望能一起多交流。Have fun~~!

上一篇 下一篇

猜你喜欢

热点阅读