iOS 尽量使用不可变对象

在设计类的时候,应充分利用属性来封装数据。而在使用属性时,则可将其声明为read-only。默认情况下属性是read-write,这样设计出来的类都是“可变的”(mutable)。如果把可变对象(mutable object)放入collection中又修改了其内容,那么就会破坏set的内部数据结构,使其失去固有的语义。因此,要尽量减少对象中的可变内容。

具体到编程实践中,应该尽量把对外公布出来的属性设为只读,而且只在有必要的时候才对外公布。如果试着改变属性值,编译器就会报错。对象中的属性值可以读取,但是不会写入。开发者在使用对象时就能确定其底层数据不会改变。

例如:

//WGPerson.h
#import 

@interface WGPerson : NSObject
@property (nonatomic, copy, readonly) NSString *firstName;
@property (nonatomic, copy, readonly) NSString *lastName;
@end

那既然这些属性都没有了setter,它的内存管理语义就失去了意义。但是从项目的可持续性考虑,我们需要在文档里指明实现所用的内存管理语义,方便以后修改。

将属性在对象内部重新声明为readwrite这一操作可于“class-continuation分类”中完成,在公共接口中声明的属性可于此重新声明,属性的其他特质必须保持不变,而readonly可扩展为readwrite。

//WGPerson.m
#import “ WGPerson.h”

@interface WGPerson : NSObject
@property (nonatomic, copy, readwrite) NSString *firstName;
@property (nonatomic, copy, readwrite) NSString *lastName;
@end

@implementation  WGPerson
        //coding
@end

现在,只能在WGPerson实现代码内部设置这些属性值了。其实更准确地说,在对象外部,仍能通过KVC技术设置这些属性,比如,可以像这样,使用“setValue:forKey:”方法来修改:

[myPerson setValue:@"myName" forKey:@"firstName"]

这样做可以改动firstName属性。因为KVC会在类里面查找“setFirstName”方法,并借此修改此属性。即便没有于公共接口中公布此方法。这种违规绕过本类所提供的API,需要程序员自己来应对可能出现的各种问题。

读Effective Objective-C 2.0 有感

你可能感兴趣的:(iOS 尽量使用不可变对象)