您的位置:首页 > 运维架构

为什么声明NSString属性时,一般使用Copy?

2017-06-28 20:53 549 查看
当突然有人会告诉我NSString的属性关键字其实应该写成copy,当时我就懵逼了,难道不是一般都写成strong吗?写了这么久的strong没发现有什么问题啊?今天我们来看看copy,这个关键词。

在举例说明之前,我们先来明确一个东西,便于理解。NSString *str = @“123”;中的str是什么?是指针,一个指向对象的指针。指针和对象都是内存块,一个大,一个小,一个在栈中,一个在堆中。那么我们将某一个对象作为参数传递的过程其实是在赋值指针。

回到cop举例,我们创建一个Person类,然后分别添加用strong和copy声明的两个属性,如图:





然后我们创建一个person实例,构造一个可变对象string作为参数传递赋值。完成初始化person实例后去修改string这个参数的值,如图:



结果如图:



由此我们可以看出,person.name的指向地址和string相同,说明他们指向同一块内存空间。但使用关键字copy修饰的person.age属性和他们的指向地址不同,但是值是相同,说明age复制了string的内容并重新开辟里内存空间保存这份内容,这也就是深复制。所以当我们对string的值进行修改的时候,由于person.name和string指向同一内存空间,所以person.name的值也相应发生了变化。而person.age和string的指向不同,还是指向原本对象@“123456789”,所以值没有发生改变。

copy一般用在NSStrign*类型、block类型上,copy产生一个副本,且返回的是一个不可变的副本,mutableCopy返回的是可变的副本。修改了副本并不会影响源对象,修改了远对象也不会影响副本,相对独立。

通过这个案例,我们可以看出,我们只是想修改string的值,却引起了属性值的变化,这样在程序运行时会造成计算错误。我们需要属性值不变,不受外界参数改变而改变,所以我们需要去设置copy关键字。但是也不是所有的NSString都用copy来修饰,如果你的属性想要跟随程序的运行而变化,就应当使用strong来修饰。建议使用copy,大多数情况下,我们声明一个不可变的对象是不希望他被修改的。

注意:当源字符串是个不可变字符串时,通过string = @“987654321”修改的string的值,发现name和age的值不会发生变化,而且name和age指针地址相同,但是string的指向地址变化了。有的时候copy也只是做潜拷贝,strong只是单纯的赋值指针,引用计数加1。至于什么是深拷贝浅拷贝,后面我们在讨论。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  nsstring 指针
相关文章推荐