assign、retain和copy的区别
来源:互联网 发布:淘宝网拍模特兼职 编辑:程序博客网 时间:2024/05/29 03:39
一、assign属性
当数据类型为int、float等原生类型时,可以使用assign,否则可能导致内存泄露。例如当使用malloc分配了一块内存,并把它的地址赋值给了指针a,后来如果希望指针b也共享这块内存,于是讲a赋值给(assgin)b。这时就用到了assgin,此时a和b指向同一块内存。但是现在问题出现了,当a不再需要这块内存时,能都直接释放呢?肯定是不能的,因为a并不知道b是否还在使用这块内存,如果a释放了,那么b在使用这块内存的时候引起程序crash掉。
二、retain属性
retain属性就是为了解决上述问题而提出的,使用了引用计数(reference counting),还是上面那个例子,我们给那块内存设一个引用计数,当内存呗分配并且赋值给a时,引用计数是1.当把a赋值给b时引用计数增加到2.这时如果a不再使用这块内存,它只需要把引用计数减1,表明自己不再拥有这块内存。b不再使用这块内存时也把引用计数减1.当引用计数变为0的时候,代表该内存不再被任何指针所引用,系统可以直接释放掉。此时系统自动调用dealloc函数,内存被回收。
三、copy属性
copy是创建一个新对象,两个对象内容相同,旧对象没有变化。新的对象retain为1,与旧有对象的引用计数不变。旧对象发生改变不影响新对象,copy减少对象对上下文的依赖。
在iOS开发中我们一般都这么定义:@property (nonatomic,copy) NSString *name,而不这么定义:@property (nonatomic,retain) NSString *name,两者的差别就在一个使用copy,一个使用retain。 这是为什么呢? 在说明白retain和copy的区别,首先需要明白深复制和浅复制的概念。
1 深复制:内容拷贝,源对象和副本对象指的是两个不同的对象,源对象引用计数器不变,副本对象引用计数器为1
2 浅复制:指针拷贝,源对象和副本对象指的都是同一个对象,对象引用计数器+1,相当于retain
只有不可变对象创建不可变副本(copy)才是浅复制,其它的都是深复制
下面通过实验来说明copy和retain的区别。
@interface ViewController ()@property (nonatomic,copy) NSString *name;@property (nonatomic,retain) NSString *name2;@end-(void)test{ NSString *str = @"我是不可变的"; self.name = str; self.name2 = str; NSLog(@" str: %p",str); NSLog(@" copy: %p",self.name); NSLog(@"retain: %p",self.name2);}-(void)test2{ NSMutableString *str = [NSMutableString stringWithString:@"我是可变的"]; self.name = str; self.name2 = str; NSLog(@" strM: %p",str); NSLog(@" copy: %p",self.name); NSLog(@"retain: %p",self.name2);}
两次执行的结果如下:
str: 0x7b140 copy: 0x7b140retain: 0x7b140 str: 0x9c142b80 copy: 0x9c140e60retain: 0x9c142b80
首先,在test中,str指向一个不可变的NSString对象,地址为0x7b140,然后str分别给name和name2赋值,由于name和name2都是NSString对象,所有都属于浅复制,赋值后都是指向str对象地址0x7b140,所有打印结果三者指向同一个对象。 其次,在test2中,str指向一个可变的NSMutableString对象,地址为0x9c140e60,然后分别给name和name2赋值,此时copy对应的name是深复制,所以会复制出另一个对象,地址为0x7c148b80。而retain对应的name2依然指向str对象地址0x9c142b80,所以打印结果是str和name2对应同一地址,name对应另一个地址。
所以得出结论:
(1)copy是创建一个新对象,两个对象内容相同,旧对象没有变化。新的对象retain为1,与旧有对象的引用计数不变。旧对象发生改变不影响新对象,copy减少对象对上下文的依赖。
(2)retain属性表示两个对象地址相同(建立一个指针,指针拷贝),内容相同,这个对象的retain值+1。两个对象要改变就一起改变。
(3)如果把一个对象赋值给另一个对象(如上面把str赋值给name或name2),如果该对象是不可变的,那么另一个对象是copy或者retain都可以,
没区别;把一个对象赋值给另一个对象,如果该对象是可变的,并且希望另一个对象随着该对象变化而变化,则可以把另一个对象设置为retain(如上面把str赋值给name2);如果希望另一个对象不随着该对象变化而变化,则可以把另一个对象设置为copy(如上面把str赋值给name)。
- retain和copy还有assign的区别
- retain和copy还有assign的区别
- retain和copy还有assign的区别
- retain和copy还有assign的区别
- retain和copy还有assign的区别
- assign、retain和copy的区别
- retain和copy还有assign的区别
- assign、retain和copy的区别
- retain\assign\copy的区别
- assign、retain、copy的区别
- retain copy assign 的区别
- assign / retain / copy区别
- retain, copy, assign区别
- retain, copy, assign区别
- retain, copy, assign区别
- retain和copy还有assign的区别,以及引用计数
- retain和copy还有assign的区别,以及引用计数
- retain、copy、assign、 strong、weak、autorelease的用法和区别
- JVM垃圾回收算法及回收器详解
- Rancher 官方在线培训-教学视频链接及内容目录
- jquery优化keyup事件
- D-City(HDU4496)
- PAT(Basic Level)_1040_有几个PAT
- assign、retain和copy的区别
- 喷水装置(一)
- 本地git仓库提交到远程仓库(或切换server地址)
- Eigen中欧拉角,旋转向量,旋转矩阵,四元数的转换
- 数组
- python练习题 21-30
- SpringBoot (一) :入门篇
- Spring Security学习笔记错误信息提示(三)
- PAT(Basic Level)_1041_考试座位号