strong weak copy assign 的用法与区别
2016-05-08 08:48
274 查看
在MRC模式下:
retain:引用计数加一,是指针拷贝,浅拷贝,在ARC中用strong代替.
assign : 修饰对象时,在ARC中用weak代替;修饰基本数据类型时和ARC中一样;
copy:和ARC中一样,一般用于NSString.
++++++++++++++++++++++++++++++++++++++++++++
原则:在ARC模式下,只要没有强指针指向对象,对象就会被销毁.
assign:不会使引用计数加一;
assign:一般用于基本数据类型,指针指向的地址一旦被释放,这些指针不会自动置为 nil。容易产生野指针.
=================================
weak:不会使引用计数加一;
weak:声明为weak的指针,指针指向的地址一旦被释放,这些指针都将被赋值为 nil。这样的好处能有效的防止野指针。
assign 指向的对象如果被释放,栈地址不会有任何的变化
weak 指向的对象如果被释放,地址会立即变化为nil
=======================================
Block属性的声明,首先需要用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的生命周期是和栈绑定的,如果不加copy修饰,当其所在栈被释放的时候,这些本地变量将变得不可访问。一旦代码执行到block这段就会导致bad
access.
使用retain也可以,但是block的retain行为默认是用copy的行为实现的,因为block变量默认是声明为栈变量的,为了能够在block的声明域外使用,所以要把block拷贝(copy)到堆,所以说为了block属性声明和实际的操作一致,最好声明为copy。
从storyboard中拖出来的控件,OC对象,delegate,一般都用weak.
Delegate为啥一般用weak修饰:
你的viewcontroller通过strong指针拥有一个UITableview,tableview的datasource和delegate都是weak指针,指向viewcontroller,防止回环,循环引用;
=================
copy:一个不可变的对象,copy后没有重新分配内存空间,这是浅拷贝,只拷贝了地址,并没有分配新的内存空间,源对象的引用计数加一,副本对象指向源对象,引用计数也加一.
一个可变的对象,mutableCopy后重新分配内存空间,这是深拷贝(拷贝内容),源对象引用计数不变,副本对象的引用计数加一.
自定义对象的拷贝都是深拷贝.
NSString和block一般都用copy.
对于可变的字符串/数组....是深拷贝,创建出新对象,指针与源对象不同;
对于不可变的字符串/数组.....是潜拷贝,不创建出新对象,指针与源对象相同;
对于NSString使用copy和strong的区别:
上面的代码声明了两个字符串属性,其中一个内存特性是strong,一个是copy。下面我们来看看它们的区别。
首先,我们用一个不可变字符串来为这两个属性赋值,
其输出结果是:
我们要以看到,这种情况下,不管是strong还是copy属性的对象,其指向的地址都是同一个,即为string指向的地址。如果我们换作MRC环境,打印string的引用计数的话,会看到其引用计数值是3,即strong操作和copy操作都使原字符串对象的引用计数值加了1。
接下来,我们把string由不可变改为可变对象,看看会是什么结果。即将下面这一句
改成:
其输出结果是:
可以发现,此时copy属性字符串已不再指向string字符串对象,而是深拷贝了string字符串,并让_copyedString对象指向这个字符串。在MRC环境下,打印两者的引用计数,可以看到string对象的引用计数是2,而_copyedString对象的引用计数是1。
此时,我们如果去修改string字符串的话,可以看到:因为_strongString与string是指向同一对象,所以_strongString的值也会跟随着改变(需要注意的是,此时_strongString的类型实际上是NSMutableString,而不是NSString);而_copyedString是指向另一个对象的,所以并不会改变。
结论
由于NSMutableString是NSString的子类,所以一个NSString指针可以指向NSMutableString对象,让我们的strongString指针指向一个可变字符串是OK的。
而上面的例子可以看出,当源字符串是NSString时,由于字符串是不可变的,所以,不管是strong还是copy属性的对象,都是指向源对象,copy操作只是做了次浅拷贝。
当源字符串是NSMutableString时,strong属性只是增加了源字符串的引用计数,而copy属性则是对源字符串做了次深拷贝,产生一个新的对象,且copy属性对象指向这个新的对象。另外需要注意的是,这个copy属性对象的类型始终是NSString,而不是NSMutableString,因此其是不可变的。
一般情况下选择copy,选择使用copy的理由是,NSString属性可能被传入一个NSString实例,也可能是一个NSMutableString实例。当传入了一个NSMutableString实例时,字符串的值可能会在背后悄悄变化
===============
strong:强引用,数组,自定义OC 对象(不是从storyboard中拖出来的),一般用strong;
@property (nonatomic,strong)UIView
*vv;
self.vv=[[UIView alloc]initWithFrame:self.view.frame];//使用strong的话,对象不会被释放,直接给属性赋值,不会有错;
self.vv.backgroundColor=[UIColor redColor];
[self.view addSubview:self.vv];
@property (nonatomic,weak)UIView
*vv;
self.vv=[[UIViewalloc]initWithFrame:self.view.frame];//用weak的话,对象还没创建就被释放了,所以给被释放的对象赋值,会报错或警告;
换成下面就可以了:
UIView *v=[[UIView alloc]initWithFrame:self.view.frame];
v.backgroundColor=[UIColorredColor];
self.vv=v;
[self.view
addSubview:self.vv];
===================
arc和mac模式的相互转换:
1.单个ARC文件转换成mrc文件:-fno-objc-arc
2.单个mrc文件转换成ARC文件:edit----------convert---------To Obj-OC
MRC 兼容ARC :mac转换成arc: -f-objc-arc
retain:引用计数加一,是指针拷贝,浅拷贝,在ARC中用strong代替.
assign : 修饰对象时,在ARC中用weak代替;修饰基本数据类型时和ARC中一样;
copy:和ARC中一样,一般用于NSString.
++++++++++++++++++++++++++++++++++++++++++++
原则:在ARC模式下,只要没有强指针指向对象,对象就会被销毁.
assign:不会使引用计数加一;
assign:一般用于基本数据类型,指针指向的地址一旦被释放,这些指针不会自动置为 nil。容易产生野指针.
=================================
weak:不会使引用计数加一;
weak:声明为weak的指针,指针指向的地址一旦被释放,这些指针都将被赋值为 nil。这样的好处能有效的防止野指针。
assign 指向的对象如果被释放,栈地址不会有任何的变化
weak 指向的对象如果被释放,地址会立即变化为nil
=======================================
Block属性的声明,首先需要用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的生命周期是和栈绑定的,如果不加copy修饰,当其所在栈被释放的时候,这些本地变量将变得不可访问。一旦代码执行到block这段就会导致bad
access.
使用retain也可以,但是block的retain行为默认是用copy的行为实现的,因为block变量默认是声明为栈变量的,为了能够在block的声明域外使用,所以要把block拷贝(copy)到堆,所以说为了block属性声明和实际的操作一致,最好声明为copy。
从storyboard中拖出来的控件,OC对象,delegate,一般都用weak.
Delegate为啥一般用weak修饰:
你的viewcontroller通过strong指针拥有一个UITableview,tableview的datasource和delegate都是weak指针,指向viewcontroller,防止回环,循环引用;
=================
copy:也是强引用,持有对象,引用计数器会加一,此属性只对那些实行了NSCopying协议的对象类型有效
copy:一个不可变的对象,copy后没有重新分配内存空间,这是浅拷贝,只拷贝了地址,并没有分配新的内存空间,源对象的引用计数加一,副本对象指向源对象,引用计数也加一.
一个可变的对象,mutableCopy后重新分配内存空间,这是深拷贝(拷贝内容),源对象引用计数不变,副本对象的引用计数加一.
自定义对象的拷贝都是深拷贝.
NSString和block一般都用copy.
对于可变的字符串/数组....是深拷贝,创建出新对象,指针与源对象不同;
对于不可变的字符串/数组.....是潜拷贝,不创建出新对象,指针与源对象相同;
对于NSString使用copy和strong的区别:
首先,我们用一个不可变字符串来为这两个属性赋值,
接下来,我们把string由不可变改为可变对象,看看会是什么结果。即将下面这一句
此时,我们如果去修改string字符串的话,可以看到:因为_strongString与string是指向同一对象,所以_strongString的值也会跟随着改变(需要注意的是,此时_strongString的类型实际上是NSMutableString,而不是NSString);而_copyedString是指向另一个对象的,所以并不会改变。
结论
由于NSMutableString是NSString的子类,所以一个NSString指针可以指向NSMutableString对象,让我们的strongString指针指向一个可变字符串是OK的。
而上面的例子可以看出,当源字符串是NSString时,由于字符串是不可变的,所以,不管是strong还是copy属性的对象,都是指向源对象,copy操作只是做了次浅拷贝。
当源字符串是NSMutableString时,strong属性只是增加了源字符串的引用计数,而copy属性则是对源字符串做了次深拷贝,产生一个新的对象,且copy属性对象指向这个新的对象。另外需要注意的是,这个copy属性对象的类型始终是NSString,而不是NSMutableString,因此其是不可变的。
一般情况下选择copy,选择使用copy的理由是,NSString属性可能被传入一个NSString实例,也可能是一个NSMutableString实例。当传入了一个NSMutableString实例时,字符串的值可能会在背后悄悄变化
===============
strong:强引用,数组,自定义OC 对象(不是从storyboard中拖出来的),一般用strong;
@property (nonatomic,strong)UIView
*vv;
self.vv=[[UIView alloc]initWithFrame:self.view.frame];//使用strong的话,对象不会被释放,直接给属性赋值,不会有错;
self.vv.backgroundColor=[UIColor redColor];
[self.view addSubview:self.vv];
@property (nonatomic,weak)UIView
*vv;
self.vv=[[UIViewalloc]initWithFrame:self.view.frame];//用weak的话,对象还没创建就被释放了,所以给被释放的对象赋值,会报错或警告;
换成下面就可以了:
UIView *v=[[UIView alloc]initWithFrame:self.view.frame];
v.backgroundColor=[UIColorredColor];
self.vv=v;
[self.view
addSubview:self.vv];
===================
arc和mac模式的相互转换:
1.单个ARC文件转换成mrc文件:-fno-objc-arc
2.单个mrc文件转换成ARC文件:edit----------convert---------To Obj-OC
MRC 兼容ARC :mac转换成arc: -f-objc-arc
相关文章推荐
- 每天一个Linux命令(10)cp命令
- page_address_init 函数
- tick_init 函数
- hadoop集群环境搭建之zookeeper集群的安装部署
- hadoop集群环境搭建之安装配置hadoop集群
- centos7 apache 虚拟目录 You don't have permission to access / on this server 解决方法
- 菜刀 ASP链接SHELL 抓包结果及分析
- 底部菜单栏之Fragment+PopupWindow实现
- windows下OpenCV在VS2010中的配置
- vs12 vs2013下open3.0配置扩展模块
- linux下 lvm 磁盘扩容
- opencv3.0使用Eigen方法进行人脸识别的方法
- linux------虚拟机的桥接模式和NAT模式的区别
- [记录]几个cheatsheet网站
- 网站渗透思路
- Linux TroubleShooting
- Linux的常用操作命令
- Linux 下的复制cp命令
- OperationalError:(1054 - "Unknown column 'game.lable1' in 'field list' ")解决办法
- Ubuntu 14.04 安装和配置Tomcat