循环引用的本质是什么?
多个对象相互都是强引用,不能释放让系统回收,对象A强引用对象B,对象B强引用对象C,对象C强引用对象A
iOS内存中的分区为:栈.堆,静态区! 栈区和静态区是操作系统自己管理回收的,不会造成循环阴影.堆区是由程序员来控制的,在堆区中的相互引用无法回收的话就会造成循环引用
解决循环引用的方式一般是将strong改为weak引用
weak:weak表示指向但是不拥有对象,引用计数器也不会增加,不需要手动销毁,内存会自动销毁
Strong:strong表示指向并且拥有对象,引用计数器增加1,引用计数器不为0时不会销毁,可强行将其修改为nil进行销毁
常见的场景就是闭包,UITabeview,Delegate,NSTimer
闭包
在copy的时候都会对block内部用到强引用的,对象A强引用对象B,对象B强引用对象C,对象C强引用对象A
在self将block作为自己的属性变量的时候,而在block的方法体里面也引用了self的本身,这就很产生了一个循环已用
处理方式为将这个self改为弱引用
在内部调用了延时函数还使用弱指针的话会取不到该指针,因为已经被销毁了,需要block内部将弱指针再强引用一下
来来来,最优质的的宏定义,OMG,用它!!!
// weak obj
/#define WEAK_OBJ(type) __weak typeof(type) weak##type = type;
// strong obj
/#define STRONG_OBJ(type) __strong typeof(type) str##type = weak##type;
Delegate
在协议的代理对象都是weak来修饰的,用strong来修饰会造成循环引用
其实在开发过程中用strong(retain)并不会发现不妥,因为功能实现就好了
在delegate属性声明的时候用strong
self ->aVC
BViewController *bVC = [[BViewController alloc] init];
bVC = self;
bVC.delegate引用计数器+1
aVC本身引用的BViewControllerDelagate,计数器+1
所以AViewControllerDelagate==Deleagate
该对象强行引用了,外部无法正常对其进行释放,所以造成了循环引用
改用weak指向该对象不被强行引用,外部可以对其进行释放