zoukankan      html  css  js  c++  java
  • copy_retain(2)区别

    属性的特性:copy和retain的区别

    1. 属性特性retain和copy的对比:

    @intertace Possession : NSObject

    {

        NSString *_possessionName;

        NSString *_possessionClass;

    }

    //我们分别将两个属性设置成不同的特性,一个为retain, 一个为copy,这样为了做个对照。

    @property (nonatomic, retain) NSString *possessionName;

    @property (nonatomic, copy) NSString *possessionClass;

     

    在生成的存方法中是这样的:

    - (void)setPossessionName:(NSString *) possessionName

    {

        [possessionName retain];  //保留一份入参,这时候possessionName的ratain计数加1。

        [_possessionName release]; //担心有一种情况出现(<1>标注),所以事先对实例变量进行释放,然后再做新的引用。

        _possessionName = possessionName; //这时候 _possessionName和possessionName指向了一个地址(也就是一个对象

                                                                参数possessionName改变的时候,实例变量也会改变)

    }

     

    - (void)setPossessionClass:(NSString *) possessionClass

    {

        [_possessionClass release]; //担心有一种情况出现(<1>标注),所以事先对实例变量进行释放,然后再做新的引用。

        _possessionClass = [possessionClass copy]; 

        //这时候 _possessionName和possessionName指向的是不同的地址(也就是不同的对象),所以即使对入参进行改变,也不会引起实例变量的改变。

    }

    测试我们的结论:

    //生成一个实例

    Possession *p = [[Possession alloc] init];

    NSMutableString *string = [NSMutableString stringWithString:@"Hello"];

    [p setPossessionName:string];

    [p setPossessionClass:string];

    NSLog(@"%@,%@",p.possessionName,p.possessionClass);

    //对string就行更改

    [string appendString:@",World"];

     

    //再打印一次

    NSLog(@"%@,%@",p.possessionName,p.possessionClass);

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

    打印结果如下:

     

     Hello,Hello

    Hello,World,Hello

     

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

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

     

    得出的结论是:

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

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

     

    注:

    <1> Possession *p = [[Possession alloc] init];

    [p setPossessionName:@"Red"];

    //接下来马上又赋一次值

    [p setPossessionName:@"Black"];

    这样的话实例变量指向@"Red"对象的引用还在,而又指向了@"Black"对象,而之前的引用不能被释放,这就造成了内存的泄露。

     

  • 相关阅读:
    动手篇:简易的首页登陆界面
    情感交流篇:HTML页面如何与后端联系
    MD5加密处理
    处女篇:自用C#后端SqlHelper.cs类
    动手篇:简单的注册界面与防SQL注入(续)
    十二省联考2019 字符串问题
    PKUWC2020游记
    uoj435 Simple Tree
    CF1303G Sum of Prefix Sums
    AGC069F Flags
  • 原文地址:https://www.cnblogs.com/flower42/p/3270465.html
Copyright © 2011-2022 走看看