写点什么

iOS 中#define 和 const

作者:NewBoy
  • 2022 年 7 月 23 日
  • 本文字数:1097 字

    阅读完需:约 4 分钟

开发场景

编写代码经常需要定义常量,例如,写一个 UI 动画,需要定义一个动画播放时间,通常做法


#define ANIMATION_DURATION 5
复制代码


这行预处理指令会把源代码中的 ANIMATION_DURATION替换为 5,可以实现需求,但是这样写不太好,其原因:


  • 代码中并没有定义出常量的类型信息,duration表示时间,但是代码中,并没有表示出它值得类型

  • 预处理指令会把碰到的所有ANIMATION_DURATION全部替换为 5


解决此问题,可以利用编译器的特性,代码如下


static const NSTimeInterval kAnimationDuration = 5;
复制代码


这样定义的好处


  • 清晰的描述了常量的含义,常量的类型

  • 命名习惯(若仅在该类.m 文件中使用,则字母前加 k,若在该类外也要使用,则加类名)



常量位置

  • 若不公开某个常量,则将其定义在该类的.m 文件


    #import "ViewController.h"    static const NSTimeInterval kAnimationDuration = 5;    @implementation ViewController    - (void)viewDidLoad {        [super viewDidLoad];        [self animation];    }    - (void)animation{        [UIView animateWithDuration:kAnimationDuration animations:^{    }];    }    @end
复制代码


注意:

变量一定要同时用staticconst来声明。const修饰符所声明的变量,如果修改就会报错static修饰符则意味着该变量仅在定义此变量的.m 文件可见


  • 对外公开某个常量(比如通知名称)

  • 此类常量需要放在“全局符号表”中,这样别的类可以使用

  • 这个常量在.h 中声明,在.m 中定义

  • 这个常量名字,最好使用与之相关的类名做前缀


#import <UIKit/UIKit.h>
@interface LoginViewController : UIViewControllerextern NSString *const LoginNoti;@end
#import "LoginViewController.h"
NSString *const LoginNoti = @"login";
@implementation LoginViewController- (void)viewDidLoad { [super viewDidLoad]; [[NSNotificationCenter defaultCenter]postNotificationName:LoginNoti object:nil];}@end

#import "ViewController.h"#import "LoginViewController.h"@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(run) name:LoginNoti object:nil];}- (void)run{ NSLog(@"run");}@end
复制代码



小结

  1. 不要用预处理指令定义常量,因为不含类型信息,而且有人改了常量值也不会报错

  2. 在实现文件里使用staticconst来定义的常量只能在该类的.m 文件中使用,此类常量不在全局符号中,所以无需加前缀

  3. 在头文件中使用extern来声明全局变量,并在相关实现文件中定义其值,这种常量要出现在全局符号表中,其名称需要加上与之相关的类名

发布于: 2 小时前阅读数: 9
用户头像

NewBoy

关注

虽不年少,艳阳高照 2019.04.10 加入

还未添加个人简介

评论

发布
暂无评论
iOS中#define和const_ios_NewBoy_InfoQ写作社区