天天看点

iOS中什么是循环引用,循环引用怎么解决循环引用的本质是什么?常见的场景就是闭包,UITabeview,Delegate,NSTimerDelegate 

循环引用的本质是什么?

多个对象相互都是强引用,不能释放让系统回收,对象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)并不会发现不妥,因为功能实现就好了

iOS中什么是循环引用,循环引用怎么解决循环引用的本质是什么?常见的场景就是闭包,UITabeview,Delegate,NSTimerDelegate 

在delegate属性声明的时候用strong

self ->aVC

BViewController *bVC = [[BViewController alloc] init];

bVC = self;

bVC.delegate引用计数器+1

aVC本身引用的BViewControllerDelagate,计数器+1

所以AViewControllerDelagate==Deleagate

该对象强行引用了,外部无法正常对其进行释放,所以造成了循环引用

改用weak指向该对象不被强行引用,外部可以对其进行释放