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"对象,而之前的引用不能被释放,这就造成了内存的泄露。

 

原文地址:https://www.cnblogs.com/flower42/p/3270465.html