1.尽量减少对象中的可变内容
正如 (八) [OC高效系列]理解对象等同性中的第6条所示,把可变内容放到collection之后,然后又改变其内容,可能会使set的内部结构发生破坏。所以尽量减少对象中的可变内容。
2.readonly,readwrite
如果一个属性对外可读,对内可读可写,那么应该在该类的公共接口处声明readonly,在类扩展中重新声明为readwrite,比如下面这个类
@interface Person : NSObject
@property (nonatomic,copy) NSString *name;
@property (nonatomic,assign) int age;
@property (nonatomic,strong) NSDate *birthday;
@property (nonatomic,readonly) NSArray *friends;
- (void)addFriend:(Person *)person;
- (void)removeFriend:(Person *)person;
@end
@interface Person ()
@property (nonatomic,readwrite,strong) NSMutableArray *friends;
@end
@implementation Person
- (instancetype)init
{
self = [super init];
if (self) {
_friends = [NSMutableArray array];
}
return self;
}
- (void)addFriend:(Person *)friend{
if(friend){
[_friends addObject:friend];
}
}
- (void)removeFriend:(Person *)friend{
if(friend){
[_friends removeObject:friend];
}
}
@end
这样用户如果想添加一个friend或者是删除一个friend就必须通过person对象本身,这样容易维持内部数据的统一性,如果直接将friends暴露出来,friend的修改对象本身并不知道,这样就很容易出bug
3.不要把可变的collection属性直接暴露出来
上面的代码还是有一定的问题,虽然公共的声明中friends为NSArray,是一个不可变的对象,但实际返回的对象依然是一个NSMutableArray,用户还是可以通过强制转换来修改。所以我们可以覆写friends的getter方法
- (NSArray *)friends{
return [_friends copy];
}
关于copy,我在 (六) [OC高效系列]弄清楚属性中也有相关的介绍
当然你也可以不覆写这个方法,因为复制也是需要损耗一些性能的。
所以在使用别人的类或者类库时,尽量使用类本身提供的对属性的设置方法,而不要绕过这些方法,否则可能会出现数据不一致的情况