第十八条:尽量使用不可变对象
这条主要讲尽量使用不可变的对象,也就是在对外属性声明的时候要尽量加上readonly修饰,默认是readwrite,这样一来,在外部就只能读取该数据,而不能修改它,使得这个类的实例所持有的数据更加安全。如果外部想要修改,可以提供方法来进行修改。
不要把可变的collection作为属性公开,而应提供相关方法,以此修改对象中的可变collection(这条个人感觉一般在常用、重要的类才有必要,毕竟也增加了不少代码量)
//Language.h
@property (nonatomic, strong) NSSet *set;
应该改为
//Language.h
@property (nonatomic, strong, readonly) NSSet *languages;
- (void)addLanguage:(NSString *)language;
- (void)removeLanguage:(NSString *)language;
//**.m
@implementation Language {
NSMutableSet *mutableLanguages;
}
- (NSSet *)languages {
return [_mutableLanguages copy];
}
- (void)addLanguage:(NSString *)language {
[_mutableLanguages addObject:language];
}
- (void)removeLanguage:(NSString *)language {
[_mutableLanguages removeObject:language];
}
第十九条:使用清晰而协调的命名方式
方法与变量名使用了“驼峰命名”,以小写字母开头,其后每个单词首字母大写。类名也用驼峰命名发,不过其首字母需要大些。
虽说使用长名字可以使代码更易读,也应该尽量言简意赅。
使用方法命名时,注意几条规则:
- 如果方法的返回值是新创建的,那么方法名的首个词应是返回值类型,除非前面还有修饰语,例如localizedString。属性的存取方法不遵循这种命名方式,因为一般认为这些方法不会创建新的对象,即便有时返回内部对象的一份拷贝,我们也认为那相当于原有的对象。
- 应该把表示参数类型的名词放在参数前面。
- 如果方法要在当前对象上执行操作,那么就应该包含动词;若执行操作时还需要参数,就在动词后面加上一个或多个名词。
- 不要使用str这种简称
- Boolean属性应该加is前缀。如果某方法返回非属性的Boolean值,那么应该根据其功能,选用has或is前缀。
- 由“输入输出”来保存返回值的方法用get前缀。
类与协议的命名:
命名方式应该协调一致。如果从其他框架中继承子类,那么务必遵循其命名惯例,例如,继承自UIView的自定义子类,那么累名末尾的词必须是view
总结:
- 起名时应遵从标准的Objective-C命名规范,这样创建出来的接口更容易为开发者所理解。
- 方法名要言简意赅。
- 方法名里不要使用缩略后的类型名称。
第二十条:为私有方法名加前缀
这条讲的是应该为类内的私有方法增加前缀,以便区分,这个感觉因人而异吧,感觉只要你不随便把私有方法暴露在.h文件都能接受
第二十一条:理解Objective-C错误模型
很多语言都有异常处理机制,Objective-C也不例外,Objective-C也有类似的@throw,不过在OC中使用@throw可能会导致内存泄漏,可能是它被设计的使用场景的问题。建议@throw只用来处理严重错误,也可以理解为致命错误(fatal error),那么处理一般错误的时候(nonfatal error)时可以使用NSError。
NSError对象里封装了3条信息:
1、Error domain(错误范围,其类型为字符串)
错误范围,也就是产生错误的根源,通常用一个特有的全局变量来定义。例:NSURLErrorDomain来表示错误范围。
2、Error code(错误码,其类型为整数)
表明在某一特定的范围内可能会发生一系列相关错误,这些错误通常采用enum来定义。
例:HTTP状态码
3、User info(用户信息,其类型为字典)
有关些错误的额外信息,其中或许包含一段“本地化的描述”(localized description)。或许还含有导致该错误发生的另外一个错误,经由此种信息,可将相关错误串成一条“错误链”(chain of errors)。
第二十二条:理解NSCopying协议
在OC开发中,使用对象时经常需要拷贝它,我们会通过copy/mutbleCopy来完成。如果想让自己的类支持拷贝,那必须要实现NSCopying协议,只需要实现一个方法:
- (id)copyWithZone:(NSZone*)zone
当然如果要求返回对象是可变的类型就要用到NSMutableCopying协议,相应方法
在拷贝对象时,需要注意拷贝执行的是浅拷贝还是深拷贝。深拷贝在拷贝对象时,会将对象的底层数据也进行了拷贝。浅拷贝是创建了一个新的对象指向要拷贝的内容。一般情况应该尽量执行浅拷贝。