您的位置:首页 > 移动开发 > IOS开发

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

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

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

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

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

static const NSTimeInterval EOCMyViewAnimationDuartion = 0.3;


//  用 const 修饰符所声明的常量如果我们试图去修改,那么编译器就会报错
// ViewController.h
static const NSString *EOCViewControllerAnimationDuartion = 0.3;

@interface ViewController : UIViewController
@end

// ViewController.m
@implementation ViewController

- (void)viewDidLoad {
EOCViewControllerAnimationDuartion = 0.4;
// 这个地方就会报错,编译器不让我们修改 const 修饰的常量
}
@end


// 用static符号修饰的变量,如果不用 static 修饰的变量此时如果是另一个单元中也声明了同名称的变量,编译器就会抛出一条错误信息

// ViewController.h
const NSString *EOCViewControllerAnimationDuartion = 0.3;

@interface ViewController : UIViewController
@end

// Other.h
const NSTimeInterval kAnimationDuartion = 0.3;
@interface Other : NSObject

// 编译器报的错误信息为:
// duplicate symbol _kAnimationDuartion in:
// Other.o
// ViewController.o


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

// ViewController.m
static const NSTimeInterval kAnimationDuartion = 0.3;

@interface ViewController ()

@end


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

// ViewController.h
static 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.h
extern NSString *const EOCNotificationStringName;
@interface ViewController : UIViewController
@end

// ViewController.m
NSString *const EOCNotificationStringName = @"Family";
@implementation ViewController
- (void)viewDidLoad {
EOCNotificationStringName = @"we are";
// 这种修饰的常量,只能定义一次,通常在声明改常量的实现文件中实现,编译器
// 会再数据段中为这个字符串分配存储空间。

}
@end


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

“别让舒适成为你青春的坟墓~”
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: