property 描述 之copy assign retain strong weak
2015-10-10 14:56
471 查看
先说后面的
retain strong 和weak
retain 和 strong是在MRC和ARC下面的不同表现形式,在ARC下,如果你用retain,会把retain转换成strong,不过两者还是有小的差别,这里不细究,自行百度(好吧,其实我不知道,过两天补充),这个就是把引用计数加一,一般对象都用这个,后面会总结
weak就是说明它是弱引用,如果它所依附的强引用释放掉,它也会跟着释放。(据我所知,主要是为了避免循环引用的)
assign 一般就是基本类型使用,不赘述
这里主要说copy,顺带说深浅拷贝
先上一个图
说白了,浅拷贝就是指针拷贝,相当于引用计数加一,不产生新对象,可以类比strong
深拷贝,就是内容拷贝,就是产生一个新对象,对象类型不是你定义的类型,而是根据你的copy类型的到的,如果是mutableCopy得到的都是可变的。普通copy得到的都是不可变的,就算你用一个可变的接收,也无法调用可变的方法。
不可变对象 copy ==对象retain (这是由于ios内存优化的原因,因为不可变对象copy创建新对象其实还是和源对象是一样的,那么分配内存的时候直接不分配了而是指向源对象retain
count就+1了,所以相当于retain)
可变对象 copy == 创建了一个新的不可变的对象
可变/不可变对象mutablecopy ==创建一个新的可变对象
有位前辈这么总结的,我觉得很好:
copy,生成的是不可变对象,无论源对象是否是可变的
mutablecopy,新对象是可变的,无论源对象是否可变
有一个例子比较形象,我引用一下
举个例子:
NSString *houseOfMM = [[NSString alloc] initWithString:'装梵几的三室两厅'];
上面一段代码会执行以下两个动作:
1 在堆上分配一段内存用来存储@'装梵几的三室两厅 ' ,比如:内存地址为0X1111
内容为 '装梵几的三室两厅',
2 在栈上分配一段内存用来存储houseForWife ,比如:地址为0XAAAA
内容自然为0X1111
下面分别看下(assign,retain,copy):
1.assign的情况:
NSString * myHouse = [
houseOfMM assign ];
此时
myHouse 和houseOfMM
完全相同,地址都是0XAAAA ,内容为0X1111
,即myHouse
只是
houseOfMM 的别名,对任何一个操作就等于对另一个操作。因此retainCount
不需要增加.(同进同出,关系好,一把钥匙,给我拿着)
2.retain的情况:
NSString * myHouse = [
houseOfMM retain ];
此时
myHouse 的地址不再为0XAAAA ,可能为0XAABB
,但是内容依然为0X1111 .因此myHouse
和
houseOfMM 都可以管理'
装梵几的三室两厅 '所在的内存。因此 retainCount
需要增加1.(有些独立,各自进出,两把钥匙)
3.copy的情况:
NSString * myHouse = [
houseOfMM copy ];
此时会在堆上重新开辟一段内存存放@'装梵几的三室两厅',比如0X1122,内容为@'装梵几的三室两厅',同时会在栈上为myHouse分配空间,比如地址:0XAACC,内容为0X1122,因此retainCount增加1供myHouse来管理0X1122这段内存.(两套@'装梵几的三室两厅',条件好,分居了,房子一人一套,所以钥匙一人一把。)
什么时候用assign,当然是破房子,简装的房子拉
基础类型(简单类型,原子类型):NSInteger,CGPoint,CGFloat,C数据类型(int,float,double,char等)
什么时候用copy
含有可深拷贝的mutable子类的类,如NSArray,NSSet,NSDictionary,NSData的,NSCharacterSet,NSIndexSet,NSString
含mutable的类,如NSMutableArray
如果用copy描述,调用self.对象=mutableArray 完了之后,这个属性就变成不可变数组了 ,所以没必要的话不要用mutable的类copy
什么时候用retain
其他NSObject和其子类对象好嘛 (大多数)
这深浅拷贝,基本上大概就了解了,而属性描述那个copy到底是可变的还是不可变的呢
肯定是不可变的啊,毕竟它是copy,不是mutableCopy
property copy 实际上就对name干了这个:
简单明了,就是copy ,也就是说,当你声明了一个用copy描述的字符串或数组
@property (nonatomic,copy)
NSMutableArray *mutableArr1;
//这里mutableArr1被copy后变为不可变的数组
NSMutableArray *mutableArr2 = [[NSMutableArrayalloc]init];
[mutableArr2 addObject:@"123"];
[mutableArr2 addObject:@"456"];
NSLog(@"%p:%@",mutableArr2,mutableArr2);
self.mutableArr1 = mutableArr2;
[self.mutableArr1addObject:@"hhhh"];
NSLog(@"%p:%@",_mutableArr1,_mutableArr1);
这样走到倒数第二行,一定会崩,因为根据上面的理论,这样调用self.mutableArr1实际上已经做了copy,生成了一个不可变的数组,不可变的数组当然不能用add方法
但是用strong的话就没问题
用copy与strong取决于需求,如果不希望被外界更改用copy,反之用strong
retain strong 和weak
retain 和 strong是在MRC和ARC下面的不同表现形式,在ARC下,如果你用retain,会把retain转换成strong,不过两者还是有小的差别,这里不细究,自行百度(好吧,其实我不知道,过两天补充),这个就是把引用计数加一,一般对象都用这个,后面会总结
weak就是说明它是弱引用,如果它所依附的强引用释放掉,它也会跟着释放。(据我所知,主要是为了避免循环引用的)
assign 一般就是基本类型使用,不赘述
这里主要说copy,顺带说深浅拷贝
先上一个图
说白了,浅拷贝就是指针拷贝,相当于引用计数加一,不产生新对象,可以类比strong
深拷贝,就是内容拷贝,就是产生一个新对象,对象类型不是你定义的类型,而是根据你的copy类型的到的,如果是mutableCopy得到的都是可变的。普通copy得到的都是不可变的,就算你用一个可变的接收,也无法调用可变的方法。
不可变对象 copy ==对象retain (这是由于ios内存优化的原因,因为不可变对象copy创建新对象其实还是和源对象是一样的,那么分配内存的时候直接不分配了而是指向源对象retain
count就+1了,所以相当于retain)
可变对象 copy == 创建了一个新的不可变的对象
可变/不可变对象mutablecopy ==创建一个新的可变对象
有位前辈这么总结的,我觉得很好:
copy,生成的是不可变对象,无论源对象是否是可变的
mutablecopy,新对象是可变的,无论源对象是否可变
有一个例子比较形象,我引用一下
举个例子:
NSString *houseOfMM = [[NSString alloc] initWithString:'装梵几的三室两厅'];
上面一段代码会执行以下两个动作:
1 在堆上分配一段内存用来存储@'装梵几的三室两厅 ' ,比如:内存地址为0X1111
内容为 '装梵几的三室两厅',
2 在栈上分配一段内存用来存储houseForWife ,比如:地址为0XAAAA
内容自然为0X1111
下面分别看下(assign,retain,copy):
1.assign的情况:
NSString * myHouse = [
houseOfMM assign ];
此时
myHouse 和houseOfMM
完全相同,地址都是0XAAAA ,内容为0X1111
,即myHouse
只是
houseOfMM 的别名,对任何一个操作就等于对另一个操作。因此retainCount
不需要增加.(同进同出,关系好,一把钥匙,给我拿着)
2.retain的情况:
NSString * myHouse = [
houseOfMM retain ];
此时
myHouse 的地址不再为0XAAAA ,可能为0XAABB
,但是内容依然为0X1111 .因此myHouse
和
houseOfMM 都可以管理'
装梵几的三室两厅 '所在的内存。因此 retainCount
需要增加1.(有些独立,各自进出,两把钥匙)
3.copy的情况:
NSString * myHouse = [
houseOfMM copy ];
此时会在堆上重新开辟一段内存存放@'装梵几的三室两厅',比如0X1122,内容为@'装梵几的三室两厅',同时会在栈上为myHouse分配空间,比如地址:0XAACC,内容为0X1122,因此retainCount增加1供myHouse来管理0X1122这段内存.(两套@'装梵几的三室两厅',条件好,分居了,房子一人一套,所以钥匙一人一把。)
什么时候用assign,当然是破房子,简装的房子拉
基础类型(简单类型,原子类型):NSInteger,CGPoint,CGFloat,C数据类型(int,float,double,char等)
什么时候用copy
含有可深拷贝的mutable子类的类,如NSArray,NSSet,NSDictionary,NSData的,NSCharacterSet,NSIndexSet,NSString
含mutable的类,如NSMutableArray
如果用copy描述,调用self.对象=mutableArray 完了之后,这个属性就变成不可变数组了 ,所以没必要的话不要用mutable的类copy
什么时候用retain
其他NSObject和其子类对象好嘛 (大多数)
这深浅拷贝,基本上大概就了解了,而属性描述那个copy到底是可变的还是不可变的呢
肯定是不可变的啊,毕竟它是copy,不是mutableCopy
property copy 实际上就对name干了这个:
1 2 3 4 | - (void)setName:(NSString *)name { _name = [name copy]; } |
@property (nonatomic,copy)
NSMutableArray *mutableArr1;
//这里mutableArr1被copy后变为不可变的数组
NSMutableArray *mutableArr2 = [[NSMutableArrayalloc]init];
[mutableArr2 addObject:@"123"];
[mutableArr2 addObject:@"456"];
NSLog(@"%p:%@",mutableArr2,mutableArr2);
self.mutableArr1 = mutableArr2;
[self.mutableArr1addObject:@"hhhh"];
NSLog(@"%p:%@",_mutableArr1,_mutableArr1);
这样走到倒数第二行,一定会崩,因为根据上面的理论,这样调用self.mutableArr1实际上已经做了copy,生成了一个不可变的数组,不可变的数组当然不能用add方法
但是用strong的话就没问题
用copy与strong取决于需求,如果不希望被外界更改用copy,反之用strong
相关文章推荐
- MainData仿Backbone Model式 数据模型记录器
- ALAssetsLibrary的使用问题:获取到ALAsset的thumbnail或者其他属性保存数组,在别地地方为nil的问题处理
- UVA Live Archive 4394 String painter(区间dp)
- 网站的高可用架构 Availability
- 论assign copy retain readonly readwrite nonatomic weak strong各自的特点
- neutron(1)veth pair
- LightOJ 1236 Pairs Forming LCM
- Scala学习笔记13【trait之多重继承、AOP实战】
- 最简实例说明wait、notify、notifyAll的使用方法
- AIX 永久修改环境变量
- 部分域名返回servfailed(案例)
- RAID在企业服务器中的应用(RAID的几种级别)
- Certificates does not conform to algorithm constraints 异常的解决方法
- 人工智能离我们还远着呢
- RAII、异常、构造函数是一家人
- 如何解决unix domain socket服务器…
- Code Forces 582 B. Once Again...(LIS)
- cvWaitKey函数说明
- 最小的图灵完备语言——BrainFuck
- weblogic启动失败:Could not obtain the localhost address 解决办法