iOS中Retain与Copy的区别

在iOS中属性的retain与copy的区别

  • retain:对象引用计数+1,本质上是指针的拷贝
    • copy:拷贝出一个新的对象,本质上是对象(地址)的拷贝

  • 例子:创建一个类
  • <span style="font-size:14px;">@interface Compare : NSObject {
        
        //为Compare类添加两个属性
        NSString *_retainString;
        NSString *_copyString;
    }
    
    //我们分别将两个属性设置成不同的特性,一个为retain, 一个为copy,这样为了做个对照。
    @property(nonatomic,retain)NSString *retainString;
    @property(nonatomic,retain)NSString *copyString;</span>

    <span style="font-size:14px;">//生成的设置方法(赋值方法)如下
    - (void)setRetainString:(NSString *)retainString {    
        //保留一份传入参数,这时候retainString引用计数加1
        [retainString retain]; 
        //避免造成内存泄露(如果省略这个代码,我们对该变量赋值两次,那么我们第二次赋值后,它持有第一次传入的对象并且没有释放,将一直存在,造成内存泄露),所以先对实例变量进行释放,然后再做新的引用
        [_retainString release];
        //这时候 _retainString 与 retainString 指向的时同一个对象(同一个地址),故而参数possessionName改变的时候,实例变量也会改变
        _retainString = retainString;   
    }
    - (void)setCopyString:(NSString *)copyString {  
        //避免造成内存泄露(如果省略这个代码,我们对该变量赋值两次,那么我们第二次赋值后,它持有第一次传入的对象并且没有释放,将一直存在,造成内存泄露),所以先对实例变量进行释放,然后再做新的引用
        [_copyString release]; 
        //这时候 _copyString 和 copyString 指向的是不同的地址(也就是不同的对象),所以即使对入参进行改变,也不会引起实例变量的改变。
        _copyString = [copyString copy];
        
    }</span>


    接下来我们进行测试

  • <span style="font-size:14px;"><span style="white-space:pre">	</span>//生成一个实例
        Compare *compare = [[Compare alloc] init]; 
        NSMutableString *string = [NSMutableString stringWithString:@"string"];
        //第一次给compare里面的两个属性赋值
        [compare setRetainString:string];
        [compare setCopyString:string];
        //第一次打印compare里面的两个属性的值
        NSLog(@"retainString = %@", compare.retainString);
        NSLog(@"copyString = %@", compare.copyString);
        
        //更改传入参数的值
        [string appendFormat:@"+append"];      //传入参数变成string+append
        
        //第二次打印compare里面的两个属性的值
        NSLog(@"retainString = %@", compare.retainString);
        NSLog(@"copyString = %@", compare.copyString);</span>


    结果如下:

  • 第一次打印结果:

  • retainString = string

    copyString = string

    第二次打印结果:
  • retainString = string+append

  • copyString = string

    这样两次打印的结果会让你明白copy和retain两个特性的明显区别

    很明显:被加以retain特性的类属性,在外界参数改变的情况下它也随之改变,说明是共用了一块内存;

    而加以copy特性的类属性,在外界参数改变的情况下它并没有随之改变,说明它只是copy了一份一模一样的内存内容。


    得出的结论是:

    如果属性的类型是可修改的子类(即该类的实例是可修改的),那么通常情况下,该属性应该有copy特性,而不是retain特性。

    这样,类实例就可以拥有一份相应对象的完全独立的备份。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值