const修饰全局变量取代宏定义
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指向的变量却是可以改变的