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

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:
也是强引用,持有对象,引用计数器会加一,此属性只对那些实行了NSCopying协议的对象类型有效

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: