iOS中Block在ARC中循环引用的原因和解决方法

经常听说block的循环应用,就是说的A引用B ,B又引用A,这样的交叉引用,导致AB都不能释放,后果就是,内存会增加,甚至导致程序崩溃。
下面通过代码来看产生的原因
首先定义一个Friend的类
1.1 Friend.h文件

import

@interface Friend : NSObject
@property(nonatomic ,copy) void(^testBlock)();
-(void)run;
@end

1.2 Friend.m文件

import "Friend.h"

@implementation Friend
添加了一个run的测试的方法
-(void)run {
NSLog(@" person run");
}
-(void)dealloc{
NSLog(@"friend被释放了");
}

2.0 在viecontroller.m文件中

  • (void)viewDidLoad {
    [super viewDidLoad];

    Friend *p = [[Friend alloc]init];
    p.testBlock =^{
    这个时候系统就会产生警告,产生了循环引用
    [ p run];
    };
    }
    3 下面来讨论产生循环引用的原因
    3.1
    Friend p = [[Friend alloc]init]; 这句代码的解释是
    当实例化一个对象的时候 这个对象的
    p 指针放在栈内存中,
    对象p存放在堆内存中。
    3.2 @property(nonatomic ,copy) void(^testBlock)();
    当我们声明一个block的成员变量的时候,这个block成员变量存放在栈中,
    但我们调用这个block用的的是copy属性 (如果没有对block用copy,block存放 在栈内存控件中),这个block就会转移到堆中,这样就会对在block中的对象产生强引用。 那么执行这句代码的时候。堆空间中的block会指向在p这个对象中用的block,这样block就会对对象p产生一个强引用,但是testblock 也是P的成员属性。 所以循环引用就产生了。
    p.testBlock =^{
    [ p run];
    };

二 Block中的循环应用的处理方法

  • (void)viewDidLoad {
    [super viewDidLoad];

    Friend *p = [[Friend alloc]init];
    下面这两句代码任选一句就可以了,但是官方推荐选用第一句

    __weak typeof (p) weakp = p;
    __unsafe_unretained typeof (p) weaka = p ;
    p.testBlock =^{
    [weakp run];
    };

}

你可能感兴趣的:(iOS中Block在ARC中循环引用的原因和解决方法)