存取方法是良好的类接口必要组成部分

Cocoa对象所有权策略有2个隐含的策略
1、如果一个对象被某方法使用了,你要确保该方法拥有该对象的所有权。就是要持有这个对象。
2、对象A接收对象B,A不应该对Brelease,除非A在B接收前已经被显式retain。

MRC中的对象setter写法如下所示:

- (void)setNameString:(NSString *)nameString {
    if (_nameString != nameString) {
        [_nameString autorelease];
        _nameString = [nameString copy];
    }
}

为啥要用copy呢?原因retain的话属性和新值都指向了同一个内存地址,你改动其中任何一个都改变了同一块内存,那如果你不需要这种情况出现,就只能复制一个了,所以用的是copy。

不过有些作为传进来的新值的对象是不能够copy的。
1、某些对象的copy的开销太大了,无论是消耗的时间,还是占用的内存。
2、某些对象,比如像视图控制器,按钮这样的,它们都是程序不可代替的组件,是不能够被复制的,作者称之为实体对象,这种情况只能传引用。

在dealloc的时候你直接在上面的setter中传nil就相当于release了。

想法是这样的,如果原来的值和新的值是同一个那啥也不用做了。如果不是,要先释放原来的值,然后再把新的值复制一份,再赋值给合成的实例变量。
为啥释放原来的值使用的是autorelease而不是release呢,据作者说,相对来说前者是线程安全的。具体场景是getter和setter同时被调用,那么getter可能返回一个不正当的值,因为在getter返回值的时候,正好是setter释放掉原来值的时候,在多线程环境下这是极有可能的。
为了防止这种问题的出现,还是先retain该值,然后再自动释放。
所以要把getter写成如下形式:

- (NSString *)nameString {
    return [[nameString retain] autorelease];
}

你可能感兴趣的:(存取方法是良好的类接口必要组成部分)