美文网首页
iOS中的static、const使用

iOS中的static、const使用

作者: 恩莱客 | 来源:发表于2021-12-01 17:15 被阅读0次

    static部分

    static分两种情况,修饰局部变量全局变量

    • 局部变量是存储在栈区的,它的⽣命周期是整个代码块,作⽤域
      也是整个代码块,⼀旦出了这个代码块,存储局部变量的这个栈
      内存就会被回收,局部变量也就被销毁了。
    局部变量
    • ⽤static修饰局部变量时,这个静态局部变量和全局变量、静态全局变量⼀样,是存储在静态存储区。存储在静态存储区,所以这块内存直到程序结束才会销毁。但是它只在声明它的代码块可 见,所以其作⽤域还是声明它的代码块。
    静态局部变量
    static修饰全局变量
    • 当全局变量没有使⽤static修饰符时,其存储在静态存储区,直到程序结束才销毁。也就是其作⽤域是整个源程序。我们可以使⽤ extern关键字来引⽤这个全局变量。
    • 当全局变量使⽤static修饰时,其⽣命周期没有变,依旧是在程序结束时才销毁。但是其作⽤只限于声明它的这个⽂件,使⽤extern关键词引⽤会报错
    extern
    为什么static修饰的变量只能在当前⽂件使⽤?
    static修饰全局变量后,该变量符号在符号表中的 Bind 属性变为local ,对于符号解析原则,当遇到了⼀个local符合⽴即解析,并 不会继续再去后续的其他源⽂件中对相应的同名全局符号进⾏解 析绑定。 (代码段?数据段?)
    所以经 static 修饰后的全局变量在本⽂件的链接期时,当这些全局符号被链接的时候会被⽴刻绑定到⽂件中相应的符号。当其他 源⽂件在链接的时候同样看到local属性的全局符号并不会对其绑 定。所以经由 static 修饰后,全局变量只在当前⽂件内有效,不 会被链接到其它⽂件中。
    dumplicate symbols 、Undefined symbols等错误提⽰都是链接器 在链接过程中发现的问题。

    编译时链接器做了什么?
    1. Mach-O ⽂件⾥⾯到有什么?
    主要就是代码和数据:代码是函数的定义;数据是全局变量的定 义,包括全局变量的初始值。不管是代码还是数据,它们的实例 都需要由符号将其关联起来。
    2. 链接器将多个Mach-O⽂件合并成⼀个
    ⼀个项⽬⾥⼀定会有多个⽂件,项⽬中⽂件之间的变量和接⼜函 数都是相互依赖的,所以这时我们就需要通过链接器将项⽬中⽣ 成的多个 Mach-O ⽂件的符号和地址绑定起来。
    没有这个绑定过程的话,单个⽂件⽣成的 Mach-O ⽂件是⽆法正常运⾏起来的。因为,如果运⾏时碰到调⽤在其他⽂件中实现的函数的情况时,就会找不到这个调⽤函数的地址,从⽽⽆法继续
    执⾏。链接器在链接多个⽬标⽂件的过程中,会创建⼀个符号表,⽤于记录所有已定义的和所有未定义的符号。链接时如果出现相同符号,就会出现“ld: dumplicate symbols”的编译错误信息;
    如果在其他⽬标⽂件⾥没有找到符号,就会提⽰“Undefined symbols”的编译错误信息。
    3. 链接器对代码主要做了哪⼏件事⼉?

    • 去项⽬⽂件⾥查找⽬标代码⽂件⾥没有定义的变量。
    • 扫描项⽬中的不同⽂件,将所有符号定义和引⽤地址收集起
      来,并放到全局符号表中。
    • 计算合并后长度及位置,⽣成同类型的段进⾏合并,建⽴绑
      定。
    • 对项⽬中不同⽂件⾥的变量进⾏地址重定位。

    总结:

    static修饰局部变量:将局部变量的本来分配在栈区改为分配
    在静态存储区,也就改变了局部变量的⽣命周期。
    static修饰全局变量:全局变量本来是在整个源程序的所有⽂
    件都可见,static修饰后,改为只在声明的那个⽂件可见,即
    修改了其作⽤域。

    const部分

    warning 解释:指针变量赋值时,赋值语句左边的指针所指向的
    类型必须具有赋值语句右边的类型所拥有的全部修饰符,才能正
    常通过编译,否则就会舍弃右边变量多余的修饰符。

    image.png

    相关文章

      网友评论

          本文标题:iOS中的static、const使用

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