美文网首页iOS开发好文面试iOS
const修饰全局变量取代宏定义

const修饰全局变量取代宏定义

作者: aLonelyRoot3 | 来源:发表于2016-07-26 01:18 被阅读806次

    const修饰全局变量取代宏定义

    宏定义

    C系程序中广泛使用宏定义,宏只是一种简单的字符串替换,根据是否带参数分为无参和带参

    // 宽高
    #define kWBCellTopMargin 8      // cell 顶部灰色留白
    #define kWBCellTitleHeight 36   // cell 标题高度 (例如"仅自己可见")
    #define kWBCellPadding 12       // cell 内边距
    #define kWBCellPaddingText 10   // cell 文本与其他元素间留白
    #define kWBCellPaddingPic 4     // cell 多张图片中间留白
    #define kWBCellProfileHeight 56 // cell 名片高度
    #define kWBCellCardHeight 70    // cell card 视图高度
    #define kWBCellNamePaddingLeft 14 // cell 名字和 avatar 之间留白
    #define kWBCellContentWidth (kScreenWidth - 2 * kWBCellPadding) // cell 内容宽度
    #define kWBCellNameWidth (kScreenWidth - 110) // cell 名字最宽限制
    
    

    开发中可能用这么一大堆的宏定义来记录某段间距, 某个视图的高度, 或者某段字符串等, 宏定义可以简单的理解为一个常量

    宏的优点

    这样做的目的在于用一个比较清楚的名称记录某个常量, 集中在某个区域管理这些常量, 在以后方便修改,修改一处便可以修改全局

    宏的缺点

    但是如果一份代码中有多处需要访问某个宏的值, 这种方法就变得不可行

    • 你可能会想到将这些宏定义放入.pch文件内,这样不就可以办到全局访问了, 但是这样会使.pch文件内部变得十分臃肿

    • 你可能又会想到将这些宏定义在一个头文件内, 然后再将这个头文件导入到.pch文件内, 这样就可以办到全局访问了, 但是这样仍然存在问题

    • 比如我的一份代码内有10处用到kWBCellTopMargin这个宏, 每次用到这个宏, 系统相当于需要分配一块临时内存给这个宏, 这样累计多了, 会比较浪费

    const修饰的全局变量

    比较好的做法应该是使用"全局常量", 类似于这种形式

    • const CGFloat AYAlpha = 0.5;
    • const NSString *AYName = @"陈洋";

    为了保证这个变量不被其他地方修改,做到只读, 使用const修饰,变量也就变为了常量

    const全局变量的优势

    • 这样也保证了常量在创建的时候, 开辟一块内存, 而全局的其他地方, 只是访问它, 不会开辟临时内存
    • 完全可以代替宏的作用

    建议做法

    为了集中管理, 分清业务逻辑, 可以在工程内单独建立一个文件管理这些"全局常量"

    一般情况, 我会在工程内搞一个名为AYConst的.h和.m文件, 注意这两个文件并不是构成一个类, 并不具备类的入口, 这样命名只是为了层次清楚

    .m文件 (保存全局常量)

    #import <UIKit/UIKit.h>
    
    const CGFloat AYCellTopMargin = 8.0;
    const CGFloat AYCellLeftMargin = 0.6;
    const CGFloat AYCellRightMargin = 0.7;
    const CGFloat AYAlpha = 1.0;
    NSString * const AYName = @"jack";
    

    .h文件(此文件导入到.pch文件, 让每个文件都可以引用)

    #import <UIKit/UIKit.h>
    
    UIKIT_EXTERN const CGFloat AYCellTopMargin;
    UIKIT_EXTERN const CGFloat AYCellLeftMargin;
    UIKIT_EXTERN const CGFloat AYCellRightMargin;
    UIKIT_EXTERN const CGFloat AYAlpha;
    UIKIT_EXTERN NSString * const AYName;
    

    我会根据需求,将.h导入合适的位置,对应使用的类也会引用到存在于.m文件中的这些全局常量

    关于UIKIT_EXTERN关键字

    UIKIT_EXTERN关键字是OC中苹果推荐的引用外部变量的关键字, 实际就是extern关键字的OC优化,作用和extern一致,引用外部变量需要的关键字

    补充知识

    关于const关键字的位置问题

    • const NSString *p;
    • NSString const *p;
    • NSString *const p;

    判断准则: 看const右侧修饰的变量是谁

    • 前两个都是修饰的*p,也就是指针指向的变量是"readOnly"的,指针p是可以指向其他内存空间的,前两种写法一致
    • 最后一个修饰的是p,也就是指针p不能再指向其他内存空间, 但是p指向的变量却是可以改变的

    相关文章

      网友评论

      • XM_Dong:宏是在栈开的内存空间吗?
        aLonelyRoot3:@XM_Dong 不是,宏是预编译的,在编译之前的,编译之后的才会分配内存,它仅仅起变量替换的作用。也就说用到它的时候,会产生一块临时内存
      • 海泉:UI类 ,要怎么搞呢?
        aLonelyRoot3:@海泉 我说了. ayconst是两个无关文件,这样命名只是规整,实际上内部我把类的入口都删了,因此它不继承自任何对象。.m文件内,只是存放这些全局常量,而.h文件只是使用extern关键字引用了这些常量。至于你说的UI类,我不清楚是什么,只建议写和全局的常量相关的东西
        海泉:恩,我是想UI类可以在AYConst里声明吗,还有AYConst 是继承NSObject吗
        aLonelyRoot3:@海泉 你可以在把常量的.h导入到pch,然后每个类都拿到了一份
      • Su_GX:学习了~
      • pengrain:学习了 :stuck_out_tongue_winking_eye:
      • 清眸如画:不错的小知识点

      本文标题:const修饰全局变量取代宏定义

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