一.assign 与weak区别
-
两者都是弱引用,assign通常用于基本数据类型,还有代理属性的修饰,weak是适用于NSObject对象,基本上来说两者是可以通用的。
-
assign其实也可以用来修饰对象。那么我们为什么不用它修饰对象呢?因为被assign修饰的对象(一般编译的时候会产生警告:Assigning retained object to unsafe property; object will be released after assignment)在释放之后,指针的地址还是存在的,也就是说指针并没有被置为nil,造成野指针。对象一般分配在堆上的某块内存,如果在后续的内存分配中,刚好分到了这块地址,程序就会崩溃掉。
-
那为什么可以用assign修饰基本数据类型?
因为基础数据类型一般分配在栈上,栈的内存会由系统自己自动处理,不会造成野指针。 -
weak修饰的对象在释放之后,指针地址会被置为nil。所以现在一般弱引用就是用weak。
weak使用场景:
- 在ARC下,在有可能出现循环引用的时候,往往要通过让其中一端使用weak来解决,比如: delegate代理属性,通常就会声明为weak。
- 自身已经对它进行一次强引用,没有必要再强引用一次时也会使用weak。比如:自定义 IBOutlet控件属性一般也使用weak,当然也可以使用strong。
二. retain和strong
他俩都是强引用,除了某些情况下不一样,其他的时候也是可以通用的。
-
在修饰block属性的时候,相信大家都知道要用copy吧,因为如果不copy的话,block是存放在栈连里面的,他的生命周期会随着函数的结束而出栈的,copy之后会放在堆里面。
-
strong在修饰block的时候就相当于copy,而retain修饰block的时候就相当于assign,这样block会出现提前被释放掉的危险
三.strong 与copy的区别
strong 与copy都会使引用计数加1,但strong是两个指针指向同一个内存地址,copy会在内存里拷贝一份对象,两个指针指向不同的内存地址
四.__block与__weak的区别
-
__block
:是用来修饰一个变量,这个变量就可以在block中被修改 -
__block
:使用 __block修饰的变量在block代码块中会被retain(ARC`下会retain,MRC下不会retain) -
__weak
:使用__weak修饰的变量不会在block代码块中被retain - 同时,在ARC下,要避免block出现循环引用 __weak typedof(self)weakSelf = self;
block变量定义时为什么用copy?block是放在哪里的?
block的循环引用并不是strong导致的…在ARC环境下,系统底层也会做一次copy操作使block从栈区复制一块内存空间到堆区…所以strong和copy在对block的修饰上是没有本质区别的,只不过copy操作效率高而已
五.代理用weak还是assign, strong
- 对于
weak
: 指明该对象并不负责保持delegate这个对象,delegate这个对象的销毁由外部控制。 - 对于
strong
:该对象强引用delegate,外界不能销毁delegate对象,会导致循环引用(Retain Cycles) - 对于
assing
:也有weak的功效。但是网上有assign是指针赋值,不对引用计数操作,使用之后如果没有置为nil,可能就会产生野指针;而weak一旦不进行使用后,永远不会使用了,就不会产生野指针。
经过一番研究,发现如果使用
@property (nonatomic, assign, readwrite) id delegate;
会有crash,报错EXC_BAD_ACCESS
声明一个delegate,那么即便delegate指向的对象销毁了,delegate中依然会保存之前对象的地址,即delegate成为了一个野指针...
而使用weak,则不会有上述问题,当delegate指向的对象销毁后,delegate = nil,
所以答案就是,使用weak
- 多多点赞,打赏更好,您的支持是我写作的动力。
本文参考 iOS学堂 的CSDN 博客 ,iOS 关于修饰代理用weak还是assign
本文参考 rootren的CSDN博客 iOS assign,weak,strong,copy 详解
网友评论