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

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];
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 存取方法(或者简单地称为“存取器”)负责获取或设置实例变量的值。他们是设计良好的类接口的必要组成部分,相当于通向对...
    花生儿阅读 267评论 0 0
  • iOS内存管理 概述 什么是内存管理 应用程序内存管理是在程序运行时分配内存(比如创建一个对象,会增加内存占用)与...
    蚊香酱阅读 5,758评论 8 119
  • 307、setValue:forKey和setObject:forKey的区别是什么? 答:1, setObjec...
    AlanGe阅读 1,577评论 0 1
  • 内存管理 简述OC中内存管理机制。与retain配对使用的方法是dealloc还是release,为什么?需要与a...
    丶逐渐阅读 1,989评论 1 16
  • Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好...
    small_Sun阅读 747评论 0 0