第五条:用枚举表示状态,选项,状态码
- 应该用枚举来表示状态机的状态,传递给方法的选项以及状态码等值,给这些值起个易懂的名字。
- 如果把传递给某个方法的选项表示为枚举类型,而多个选项又可以同时使用,那么就将各选项定义为2的幂,以便通过按位操作将其组合起来。
用
NS_ENUM
与NS_OPTIONS
宏来定义枚举类型,并指明其底层数据类型。1
2
3
4
5typedef NS_ENUM(NSUInteger, EOCConnectionState) {
EOCConnectionStateDisconnected,
EOCConnectionStateConnecting,
EOCConnectionStateConnected
}1
2
3
4
5
6typedef NS_OPTIONS(NSUInteger, EOCPermittedDirection) {
EOCPermittedDirectionUP = 1<<0,
EOCPermittedDirectionDown = 1<<1,
EOCPermittedDirectionLeft = 1<<2,
EOCPermittedDirectionRight = 1<<3,
}在处理枚举类型的switch语句中不要实现default分支。
第六条:理解属性的概念
- 属性自动生成的
setter
,getter
方法是由编译器在编译器执行,所以编译器里看不见这些合成方法
。 @synthesize
可以指定合成方法
所对应的实力变量的名称,但不推荐这么做。1
@synthesize firstName = _myFirstName;
@dynamic
不会自动生成合成方法
,如果代码访问了合成方法
也不会报错,(多用于CoreData中,因为某些属性不是实例变量,而是来自数据库中)在初始化方法中不要使用setter方法,如果遇到字符串类型属性要注意copy
1
2
3
4
5
6
7
8- (id)initWithFirstName:(NSString *)firstName LastName:(NSString*)lastName {
self = [super init];
if(self){
_firstName = [firstName copy];
_lastName = [lastName copy];
}
return self;
}
- 属性自动生成的
第七条:在对象内部尽量直接访问实例变量
计较推荐的方案是:
写入实例变量通过点语法(
setter
)读取实例变量通过实例变量直接访问
但有个例外的情况:
首先大部分情况下初始化方法和dealloc中要使用直接访问实例变量的方法,因为子类可能会覆写
setter
方法,导致初始化的时候出现我们不想要的结果。但某些情况下却必须在初始化方法中使用
setter
方法,比如待初始化的实例变量声明在父类中,而我们又无法直接访问此实例变量,那么就需要通过setter
方法了。
还有当使用懒加载的情况下就必须通过
getter
方法了,否则将略过懒加载的过程。
第八条:理解“对象等同性”
- 检测对象的等同性,需要提供
isEqual
,hash
两个方法。 - 相同的对象具有相同的哈希码,当相同的哈希码却不一定是相同的对象。
- 按照具体需求制定检测方法。
- 编写hash时要选择合适的算法。
- 检测对象的等同性,需要提供