谈谈为何iOS开发别用宏来定义常量

2020-01-15 17:52:41王振洲

首先,预处理命令他不是一个常量!!!!

我们来看一段代码


#define avatar @"60"
 if (false) {
  #define avatar @"80"
 }
 NSLog(avatar);

这段代码会输出多少,我们将“avatar”定义为了60,然后在一个永远不会执行的代码里面重新定义了“avatar”为80,if语句中的代码永远不会执行,但是在编译时期,编译器会编译这段代码,而这个时候编译器就会将avatar这个名字替换为@“80”,所以这段代码最后的输出结果就是80。

当然这个时候编译器是会有一个警告的,但是不知道有多少同学会忽略这个警告。或者你会告诉我你对警告十分敏感,不会放过他的,但是记住你不是一个人在写代码,可能在别人的页面他给你重新定义了你的define,给你挖了一个大坑,还找不着.........

用const来定义一个常量

const修饰符定义的变量是不可变的,比如说你需要定义一个动画时间的常量,你可以这么做:


static const NSTimeInterval kAnimateDuration = 0.3;

当你试图去修改“ kAnimateDuration”的值的时候,编译器会报错。更加重要的是用这种方法定义的常量是带有类型信息的,而这点则是define不具备的。

也许你已经发现了,如果你像这样定义:


static const NSString * kUserName = @"StrongX";

你是可以修改userName的值的,(说好的常量呢~~~)

首先我们需要确定的是以下两种写法是一样的:


static NSString const * kUserName = @"StrongX";
static const NSString * kUserName = @"StrongX";


也就是说const放在类型前还是类型后是一样的效果。然后不同效果的是下面这种写法:


static NSString * const kUserName = @"StrongX";

const 修饰的是他右边的部分,也就是说:


static NSString const * kUserName = static NSString const (* kUserName )

static NSString * const kUserName = static NSString * const (kUserName)

当const修饰的是(userName)的时候,不可变的是userName;“*”在C语言中表示
指针指向符,也就是说这个时候userName指向的内存块地址不可变,而内存保存的内容是可变的,我们来做个尝试:


 NSLog(@"内存地址: %x",& kUserName);
 kUserName = @"superXLX";
 NSLog(@"内存地址: %x",& kUserName);

以上NSLog会打印*userName指向的内存块地址,而他的输出是:

ios,定义常量,常量,宏定义