方案一:使用__block修饰符
- 原理:__block修饰符修饰的变量,其内存管理方式会有所改变。在Block内部对其引用时,不会增加其引用计数,从而打破循环引用。
- 实现方式:在声明变量时使用__block修饰,例如:
__block id obj = [[NSObject alloc] init];
void (^block)(void) = ^{
NSLog(@"%@", obj);
};
block();
方案二:使用__weak(ARC环境下)或__unsafe_unretained(MRC环境下)修饰符
- 原理:__weak(ARC)或__unsafe_unretained(MRC)修饰的变量,在被Block引用时,不会增加其引用计数。__weak在对象释放时会自动将指针置为nil,而__unsafe_unretained不会自动置nil,使用时需注意野指针问题。
- 实现方式:
// MRC环境下
__unsafe_unretained id obj = [[NSObject alloc] init];
void (^block)(void) = ^{
NSLog(@"%@", obj);
};
block();
[obj release];
// ARC环境下类似,只是将__unsafe_unretained换成__weak
__weak id obj = [[NSObject alloc] init];
void (^block)(void) = ^{
NSLog(@"%@", obj);
};
block();
方案三:在Block执行完毕后手动断开循环引用
- 原理:在Block执行完后,手动将Block或Block内部强引用的对象设置为nil,从而打破循环引用。
- 实现方式:
id obj = [[NSObject alloc] init];
__block void (^block)(void);
block = ^{
NSLog(@"%@", obj);
block = nil; // 执行完Block后将其设为nil
};
block();
[obj release];