第十六条:提供“全能初始化方法”
一个类中可能有多个初始化方法,但是在设计中需要制定其中一个方法为全能初始化方法,每个初始化方法都需要先调用这个全能初始化方法。
例如有这样一个类:EOCRectangle
1
2
3
4
5
6
7
8
9@interface EOCRectangle: NSObject
@property (nonatomic, assign, readonly) CGFloat width;
@property (nonatomic, assign, readonly) CGFloat height;
- (instancetype) initWithWidth:(CGFloat)width
andHeight:(CGFloat)height;
@end一下是我们定义的全能初始化方法
1
2
3
4
5
6
7
8
9- (instancetype) initWithWidth:(CGFloat)width
andHeight:(CGFloat)height{
self = [super init];
if(self){
_width = width;
_height = height;
}
return self;
}再定义一个类EOCSquare 继承自EOCRectangle
1
2
3
4
5
6
7
8
9
10
11
12
13
@interface EOCSquare : EOCRectangle
- (instancetype) initWithDimension:(CGFloat)dimension;
@end
- (instancetype) initWithDimension:(CGFloat)dimension {
return [self initWithWidth:dimension andHeight:dimension];
}由于EOCSquare可以调用父类的方法,有可能出现无意中调用了
- (instancetype) initWithWidth:(CGFloat)width andHeight:(CGFloat)height
这个方法,造成 生成的EOCSquare对象的不是一个正方形,可以采用下面的这种方法覆写全能初始化方法1
2
3
4
5- (instancetype) initWithWidth:(CGFloat)width
andHeight:(CGFloat)height{
float dimension = MAX(width, height);
return [self initWithDimension:dimension];
}
第十七条:实现description方法
自定义类中,如果想要通过
NSLog
打印对象信息,则需要重写NSObject
中的- (NSString *)description
方法。如果是想通过调试器命令po
打印对象信息则需要重写- (NSString *)debugDescription
方法。第十八条:尽量使用不可变对象
在类外部暴露的属性尽量设置成
readonly
属性,已防止用户进行没必要的修改。如果需要在类内部进行修改,可以通过分类的方式,在.m文件中重新定义相同名称的属性为readwrite
,这样就可以在类内部的实现中进行修改。例如:1
2
3
4
5
6@interface EOCPointOfInternet : NSObject
@property (nonatomic, copy, readonly) NSString *identifier;
@property (nonatomic, copy, readonly) NSString *title;
@end1
2
3
4
5
6
7
8
9
10
11
12@import "EOCPointOfInternet.h"
@interface EOCPointOfInternet ()
@property (nonatomic, copy, readwrite) NSString *identifier;
@property (nonatomic, copy, readwrite) NSString *title;
@end
@implementation EOCPointOfInternet
@end但这样会产生另外一个问题,在类的外部仍然可以通过
KVC
的方式设置这些属性值,比如1
pointOfInternet setValue:@"abc" forKey@"identifier"];
这种方法是通过
KVO
的方式去类中查找setIdentifier
方法,即便该类没有公布此方法也可以使用。但并不推荐使用还有如果属性中包含各种collection类型的属性,依然推荐采取不可变的形式,例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26@interface EOCPerson : NSObject
@property (nonatomic, strong, readonly) NSSet *friends
- (void)addFriend:(EOCPerson *)person;
- (void)removeFriend:(EOCPerson *)person;
@end
NSMutableSet *_internalFriends;
}
- (NSSet *)friends {
return [_internalFriends copy];
}
- (void)addFriend:(EOCPerson *)person {
[_internalFriends addObject:person];
}
- (void)removeFriend:(EOCPerson *)person {
[_internalFriends removeObject:person];
}通过这种方式类的内部维护着一个可变的
collection
,而暴露出来的属性是不可变的。