property中的copy属性

6 篇文章 0 订阅
5 篇文章 0 订阅

       在声明property属性时,如果是一个NSString的变量,那么绝大多数情况下都要用到copy,这是为什么呢?这是因为用了copy之后更加安全,减少了代码之间的耦合度,属性的值更不容易被改变。

 

首先要明白两个概念,深复制与浅复制的区别:

深复制:复制对象的内存区域和指针,复制后的对象与原有对象相互独立

浅复制:仅仅复制指针,复制后两个指针指向同一块内存区域,复制后的对象与原有对象相互影响

 

明白了这两个概念就更容易理解了,先通过如下的例子直观了解一下copy的好处:

首先定义了一个HITStudent类,里面包含了一个用copy修饰的stuName属性和一个被assign修饰的stuNumber属性,此处nonatomic是线程安全的意思,如果不写默认为atomic。

#import <Foundation/Foundation.h>

@interface HITStudent : NSObject

@property (nonatomic,copy)NSString *stuName;

@property (nonatomic,assign)NSString *stuNumber;

@end


在主函数中先创建一个名为stu1的HITStudent对象,并把该对象的stuName属性和stuNunber属性分别赋值为xgc和123,之后我们对可变字符串name和number进行修改,再次打印stu1的两个属性我们发现用了copy修饰的stuName属性没有变化,但是用assign修饰的stuNumber属性的值却被改变了。

#import <Foundation/Foundation.h>

#import "HITStudent.h"

int main(int argc,constchar * argv[]) {

    @autoreleasepool {

        HITStudent *stu1 = [[HITStudentalloc]init];

        NSMutableString *name = [NSMutableStringstringWithFormat:@"xgc"];

        NSMutableString *number = [NSMutableStringstringWithFormat:@"123"];;

        stu1.stuName = name;

        stu1.stuNumber = number;

        NSLog(@"学生的姓名为:%@",stu1.stuName);

        NSLog(@"学生的号码为:%@",stu1.stuNumber);

        

        [name appendString:@"HIT"];

        [number appendString:@"456"];

        NSLog(@"更改后学生的姓名为:%@",stu1.stuName);

        NSLog(@"更改后学生的号码为:%@",stu1.stuNumber);

    

    }

    return0;

}


打印结果如下:

2016-04-18 10:44:06.025 copy[1230:46766]学生的姓名为:xgc

2016-04-18 10:44:06.027 copy[1230:46766]学生的号码为:123

2016-04-18 10:44:06.027 copy[1230:46766]更改后学生的姓名为:xgc

2016-04-18 10:44:06.027 copy[1230:46766]更改后学生的号码为:123456

Program ended with exit code: 0


由此我们可以得出结论:使用copy修饰NSString的时候,如果可变字符串改变了,被可变字符串的属性不会改变


下面我们来分析一下原理:

assign和copy实际上是通过set方法来进行内存管理,当我们在ARC模式下使用assign时,系统会自动生成如下set方法:

-(void)setStuName:(NSString *)stuName

{

    _stuName = stuName;

}


而使用copy时会生成如下set方法:

-(void)setStuName:(NSString *)stuName

{

    if (_stuName != stuName) {

        [_stuName release];

        _stuName = [stuNamecopy];

    }



具体来说,assign是直接赋值,让属性与原来的可变字符串指向了同一块内存区域,这样的话当可变字符串指向的内存区域的值改变的时候,属性的值自然也跟着改变,赋值相当于浅复制;

而copy的本质是先release原有的值,再复制该内存所储存的内容,可以理解为先做了一次release,又做了一次retain,但之后得到了一个全新的对象,拥有不同的内存区域,因此改变原有的字符串不会对属性的值产生影响,copy赋值相当于深复制。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值