文章目录
一、用前缀避免命名空间冲突
1.为什么用前缀避免明明冲突
OC中没有其他语言那种内置的命名空间机制(namespace),所以我们在对文件命名时要避免潜在的命名冲突,若是发生重名冲突,那么应用程序相应的链接过程就会出错,因为其中出现了重复的符号。例如:
这个错误就是因为两份代码都各自实现的EOCTheClass类导致该类所对应的类符号和“元类”符号各定义了两次。又恰好出现在同一个项目中并且重名,导致编译器无法识别,而出错了。
比无法链接更糟糕的清况是,在运行期载入了含有重名类的程序库。此时,“动态加载器”就遭遇了“重名符号错误”,很可能会令整个应用程序崩溃。
2.应当如何避免
避免此问题的唯一办法就是变相实现命名空间:为所有名称都加上适当前缀。所选前缀可以是与公司、应用程序或二者皆有关联之名。即使加了前缀也可能出现命名冲突,但是几率会小很多。
使用Cocoa创建应用程序时一定要注意,Apple宣称其保留使用所有“两字母前缀”的权利,所以你自己选用的前缀应该是三个字母的。
不仅是类名,应用程序中的所有名称都应加前缀。如果要为既有类新增“分类”,那么一定要给“分类”及“分类”中的方法加上前缀,开发者可能会忽视另外一个容易引起命名冲突的地方,那就是类的实现文件中所用的纯C函数及全局变量,在编译好的目标文件中,这些名称是要算做“顶级符号”的。
3.要点
- 选择与你的公司、应用程序或者二者皆有关联的名称作为类名的前缀,并在所有代码中均使用这一前缀。
- 若是自己所开发的程序库中用到了第三方库,则应为其中的名称加上前缀。
二、提供“全能初始化方法”
1.什么是全能初始化方法
所有对象均要初始化。初始化时,有些对象可能无须开发者向其提供额外信息,不过一般来说还是要提供的。以iOS的UI框架UIKit为例,其中有个类叫做UITableViewCell,初始化该类对象时,需要指明其样式及标识符,标识符能够区分不同类型的单元格。由于这种对象的创建成本较高,所以绘制表格时可依照标识符来复用,以提升程序效率。我们把这种可为对象提供必要信息以便其能完成工作的初始化方法叫做“全能初始化方法”。
如果创建类实例的方法不止一种,那么这个类就会有多个初始化方法。这当然很好,不过仍然要在其中选定一个作为全能初始化方法,令其他初始化方法都来调用它。NSDate就是个例子,其初始化方法如下:
- (id)init
- (id)initWithString: (NSString *)string
- (id)initWithTimeIntervalSinceNow: (NSTimeInterval)seconds
- (id)initWithTimeInterval: (NSTimeInterval)seconds sinceDate: (NSDate *)refDate
- (id)initWithTimeIntervalSinceReferenceDate: (NSTimeInterval)seconds
- (id)initWithTimeIntervalSince1970: (NSTimeInterval)seconds
正如该类的文档所描述的那样,在上面几个初始化方法中,“initWithTimeIntervalSinceReferenceDate:”是全能初始化方法。也就是说,其余的初始化方法都要调用它。于是,只有在全能初始化方法中,才会存储内部数据。这样的话,当底层数据存储机制改变时,只需修改此方法的代码就好,无须改动其他初始化方法。
比如说,我们要编写一个表示矩形的类。其接口可以这样写:
#import <Foundation/Foundation.h>
@interface EOCRectangle : NSObject
@property (nonatomic, assign, readonly) float width;
@property (nonatomic, assign, readonly) float height;
@end
2.如何重写初始化方法
首先需要在你新的初始化方法中的调用这个类的“全能初始化方法”,如果他是继承关系的话,那么就使用super来调用父类的初始化方法,调用结束之后就可以为想要实现的初始化方法添加逻辑,总而言之,全能初始化方法的调用链一定要维持。**如果子类的全能初始化方法与超类方法的名称不同,我们总应覆写超类的全能初始化方法,避免子类调用父类的全能初始化方法。**但是,有时候我们可能不想覆写超类的全能初始化方法,因为那样做没有道理,那么我们就可以覆写超类的全能初始化方法,让在调用这个方法的时候抛出异常,这样就可以确保用户一定使用的是你自己定义的方法了。
3.一个类有多个全能初始化方法要注意的问题
通常我们遇到的类都只有一个全能初始化方法,但是偶尔也有类具有多个全能初始化方法。
由于这两种初始化方法的解码方式不同,而且我们也不能人为的改变其解码的方式,那么我们就只能顺其自然,他有两种我们也重写两种初始化方法&#