IOS 开发笔记——使用类型常量,少用预处理命令

来源:互联网 发布:淘宝店铺号搜不到 编辑:程序博客网 时间:2024/06/05 21:00

以前我们在开发中难免要提取常量,例如学过 C 的同学们,包括我以前也会把按钮的宽度使用预处理命如: #define buttonWidth 80 这种方法来为提取。但是这样做的话会有一个缺点,那就是当我们预处理过程会把碰到的所有buttonWidth都换成80,这样的话,假设指令声明再某个头文件中,那么所有引入这个头文件的代码,其buttonWidth都会被替换。

如果我们在头文件中使用#define 的话常量名称总是有可能冲突的,如果一个常量被改变了,那么就会导致所有用到这个常量的文件发生了改变,但是这不是我们想要的,既然我们声明一个常量,目的就是不让它改变嘛。

那么想当然我们要做出解决方案了,苹果公司推荐的方案是使用以下方案:

例如一个播放动画的提取常量为0.3秒,那么我们就这么声明

static const NSTimeInterval EOCMyViewAnimationDuartion = 0.3;
//  用 const 修饰符所声明的常量如果我们试图去修改,那么编译器就会报错// ViewController.hstatic const NSString *EOCViewControllerAnimationDuartion = 0.3;@interface ViewController : UIViewController@end// ViewController.m@implementation ViewController- (void)viewDidLoad {  EOCViewControllerAnimationDuartion = 0.4;  // 这个地方就会报错,编译器不让我们修改 const 修饰的常量}@end
// 用static符号修饰的变量,如果不用 static 修饰的变量此时如果是另一个单元中也声明了同名称的变量,编译器就会抛出一条错误信息// ViewController.hconst NSString *EOCViewControllerAnimationDuartion = 0.3;@interface ViewController : UIViewController@end// Other.hconst NSTimeInterval kAnimationDuartion = 0.3;@interface Other : NSObject// 编译器报的错误信息为:// duplicate symbol _kAnimationDuartion in:// Other.o// ViewController.o

但是我们一般情况下都应该把常量类型都放在实现文件中,这样的母的是让 static 关键字来修饰此变量后,此变量仅在仅在定义此变量的”编译单元”(一般我们指.m 文件)中可见

// ViewController.mstatic const NSTimeInterval kAnimationDuartion = 0.3;@interface ViewController ()@end

同时如果我们用此方法在头文件中声明了kAnimationDuartion 变量,如果我们在引入声明这个变量的头文件到其他头文件的时候,虽然这个其他文件是不可可以更改kAnimationDuartion这个变量的值的,但是也是可以访问到kAnimationDuartion这个变量的。我们为了让这个常量名与其他文件的常量名不发生冲突,应该把kAnimationDuartion这个常量声明放在”编译单元”(一般我们指.m 文件)中

// ViewController.hstatic const NSTimeInterval kAnimationDuartion = 0.3;@interface ViewController : UIViewController@end// Other.m#import "Other.h"#import "ViewController.h"@implementation Other- (void)hello {    kAnimationDuartion    // 这个变量也是可以访问到的,如果此文件中有跟kAnimationDuartion同名称的变量,这样就发生冲突了}@end

注意:
我们也使用了 EOCMyView作为前序来表明所属类来区分其他常量的名称。

如果我们需要使用到其他文件也要访问的这个常量的值,也就是对外公开某个常量,比如说我们发送通知,那么一个对象注册通知,另一个对象发送通知,双方都要用到通知的名字,那么我们该用何种方法呢?
那么苹果推荐的方法如下:

// 头文件中 .h 文件extern NSString *const EOCNotificationStringName;// 实现文件 .m文件NSString *const EOCNotificationStringName = @"Family";// 这个例子应该是从右到左读,这个例子中 EOCString这个常量是一个指针,他指向 NSString 对象// extern 关键字就是告诉编译器将会有 EOCString 这么一个符号,编译器无须查看它的定义,允许代码使用此常量

这里头文件文件实现对外声明,让外界引入此文件后访问到EOCNotificationStringName这个通知,实现文件进行EOCNotificationStringName的定义。

// 当我们不希望有人改变这个指针常量,使其只想另一个 NSString 对象// 的时候就调用这种方法声明,因为用这种方法声明的变量只会被定义一次,之后// 再次定义,编译器就会发出警告// ViewController.hextern NSString *const EOCNotificationStringName;@interface ViewController : UIViewController@end// ViewController.mNSString *const EOCNotificationStringName = @"Family";@implementation ViewController- (void)viewDidLoad {  EOCNotificationStringName = @"we are";  // 这种修饰的常量,只能定义一次,通常在声明改常量的实现文件中实现,编译器 // 会再数据段中为这个字符串分配存储空间。}@end

好了,我们先写到这里结束了,如果你觉得还可以,请关注一下作者,作者会不断在空闲时间写下一些自己对 IOS 某些模块的总结与笔记供大家阅读查考,谢谢。

“别让舒适成为你青春的坟墓~”

0 0
原创粉丝点击