iOS基础篇-Copy和Strong
本文仅针对使用字符串、数组、字典时,对copy和Strong展开讨论
1.不可变字符串
申明copy和strong属性字符串
@property (strong, nonatomic) NSString *strStrong;
@property (copy, nonatomic) NSString *strCopy;
// 不可变字符串
NSLog(@"不可变字符串:");
NSString *str = @"aaaa";
NSLog(@"str= %@内存地址 = %p 指针地址 = %p",str,str,&str);
self.strStrong = str;
NSLog(@"strong= %@内存地址 = %p 指针地址 = %p",self.strStrong,self.strStrong,&_strStrong);
self.strCopy = str;
NSLog(@"copy= %@内存地址 = %p 指针地址 = %p\n",self.strCopy,self.strCopy,&_strCopy);
打印结果
不可变字符串:
str= aaaa内存地址 = 0x104ec4098 指针地址 = 0x7ffeead3bbd8
strong= aaaa内存地址 = 0x104ec4098 指针地址 = 0x7fe70100e600
copy= aaaa内存地址 = 0x104ec4098 指针地址 = 0x7fe70100e608
对不可变字符串进行操作:
str = @"bbb";
NSLog(@"对不可变字符串操作后:");
NSLog(@"str= %@内存地址 = %p指针地址 = %p",str,str,&str);
NSLog(@"strong= %@内存地址 = %p指针地址 = %p",self.strStrong,self.strStrong,&_strStrong);
NSLog(@"copy= %@内存地址 = %p指针地址 = %p\n",self.strCopy,self.strCopy,&_strCopy);
打印结果
对不可变字符串操作后:
str= bbb内存地址 = 0x104ec4118指针地址 = 0x7ffeead3bbd8
strong= aaaa内存地址 = 0x104ec4098指针地址 = 0x7fe70100e600
copy= aaaa内存地址 = 0x104ec4098指针地址 = 0x7fe70100e608
结论:源对象为不可变字符串而言,不论使用copy还是strong属性,所对应的值是不发生变化,strong和copy并没有开辟新的内存,即并不是深拷贝。此时,使用copy或是strong,并没有对数据产生影响。 2.可变字符串
// 可变字符串
NSLog(@"可变字符串:");
NSMutableString *mutableStr = [[NSMutableString alloc] initWithString:@"kobe"];
NSLog(@"mutableStr = %@ 内存地址 = %p指针地址 = %p",mutableStr,mutableStr,&mutableStr);
self.strStrong = mutableStr;
NSLog(@"strong= %@ 内存地址 = %p指针地址 = %p",self.strStrong,self.strStrong,&_strStrong);
self.strCopy = mutableStr;
NSLog(@"copy= %@ 内存地址 = %p指针地址 = %p\n",self.strCopy,self.strCopy,&_strCopy);
打印结果
可变字符串:
mutableStr = kobe 内存地址 = 0x60000005b150指针地址 = 0x7ffeead3bbd0
strong= kobe 内存地址 = 0x60000005b150指针地址 = 0x7fe70100e600
copy= kobe 内存地址 = 0xa00000065626f6b4指针地址 = 0x7fe70100e608
对可变字符串进行操作:
NSLog(@"对可变字符串操作后:");
[mutableStr appendString:@"-bryant"];
NSLog(@"mutableStr = %@ 内存地址 = %p指针地址 = %p",mutableStr,mutableStr,&mutableStr);
NSLog(@"strong= %@ 内存地址 = %p指针地址 = %p",self.strStrong,self.strStrong,&_strStrong);
NSLog(@"copy= %@ 内存地址 = %p指针地址 = %p",self.strCopy,self.strCopy,&_strCopy);
打印结果
对可变字符串操作后:
mutableStr = kobe-bryant 内存地址 = 0x60000005b150指针地址 = 0x7ffeead3bbd0
strong= kobe-bryant 内存地址 = 0x60000005b150指针地址 = 0x7fe70100e600
copy= kobe 内存地址 = 0xa00000065626f6b4指针地址 = 0x7fe70100e608
结论:数据源为可变字符串而言,使用copy申明属性,会开辟一块新的内存空间存放值,源数据不论怎么变化,都不会影响copy属性中的值,属于深拷贝;使用strong申明属性,不会开辟新的内存空间,只会引用到源数据内存地址,因此源数据改变,则strong属性也会改变,属于浅拷贝。 在实际开发中,我们不希望源数据改变影响到属性中的值,故而使用copy来申明。
3.属性为可变数组、可变字典
例如:当我们使用copy修饰NSMutableArray时
@property (copy, nonatomic) NSMutableArray *originArray;
self.originArray = [NSMutableArray arrayWithCapacity:0];
NSLog(@"self. originArray class name %@",[self.originArray class]);
打印结果:self. originArray class name __NSArrayI
【iOS基础篇-Copy和Strong】我们可以看到,copy申明的可变数据,初始化或复值之后,变成不可变数组,对数组执行增,删会跑出错误。这是因为copy属性修饰后,在初始化或赋值时,会先执行copy操作,然后赋值。
结论:在实际开发中,我们需要对可变数组、字典使用strong属性修饰。
推荐阅读
- 2018年11月19日|2018年11月19日 星期一 亲子日记第144篇
- 《魔法科高中的劣等生》第26卷(Invasion篇)发售
- 拍照一年啦,如果你想了解我,那就请先看看这篇文章
- 2020-04-07vue中Axios的封装和API接口的管理
- 亲子日记第186篇,2018、7、26、星期四、晴
- 漫画初学者如何学习漫画背景的透视画法(这篇教程请收藏好了!)
- iOS中的Block
- 两短篇
- Python基础|Python基础 - 练习1
- 第四十三篇接纳孩子的感受