美文网首页
iOS 尽量使用不可变对象

iOS 尽量使用不可变对象

作者: Wougle | 来源:发表于2018-01-28 12:37 被阅读0次

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

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

    例如:

    //WGPerson.h
    #import <Foundation/Foundation.h>
    
    @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 尽量使用不可变对象

          本文链接:https://www.haomeiwen.com/subject/thiaaxtx.html