美文网首页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指向的变量却是可以改变的

相关文章

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

    const修饰全局变量取代宏定义 宏定义 C系程序中广泛使用宏定义,宏只是一种简单的字符串替换,根据是否带参数分为...

  • 0926-const,static,extern关键字

    1、用法 const: 被const修饰的变量是只读的,不可更改。推荐使用const来替代宏定义,宏定义不会报错 ...

  • static和const的用法

    [推荐文章]:oscarwin的面试总结 const的作用 const修饰全局变量; const修饰局部变量; c...

  • C++

    1.c++基础 1.定义修饰付#define XX 8 修饰宏常量,不可修改const int a = 5; co...

  • const 宏 static extern

    IOS 基础-define、const、extern、全局变量 const 与 宏的区别 : C语言宏高级用法 [...

  • static,const,extern

    const 1.const只修饰右边的值 2.const会编译检查,会报编译错误,宏定义是预编译(编译之前处理) ...

  • const、static、extern使用

    const作用: 1.修饰右边指针变量和基础变量 2.被修饰的变量不可变 const使用场景: 修饰全局变量---...

  • iOS 正确使用const,static,extern

    const与宏的区别const 修饰的常量即便是声明在A类的.m文件中,在B类中也不能定义同名的常量。宏是预编译(...

  • OC-const、static、#define使用

    一、const const修饰符可以修饰指针类型、基本数据类型、设置常量 ,编译检查,比宏更加安全 1.const...

  • const常量与define宏定义的区别

    在C++ 程序中只使用const常量而不使用宏常量,即const常量完全取代宏常量。以下是const和define...

网友评论

  • 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