Block循环引用问题(Objective-c)

造成循环引用的简单理解是:Block的拥有者在Block作用域内部又引用了自己,因此导致了Block的拥有者永远无法释放内存,就出现了循环引用的内存泄漏

示例代码

@interface ObjTest () {
NSInteger testValue;
}
@property (copy, nonatomic) void (^block)();
@end @implement ObjTest
- (void)function {
/*
//这里会循环引用
self.block = ^() {
self.testValue = 100;
}; */ __weak ObjTest* weakSelf = self;//使用弱引用,解决循环引用问题
self.block = ^() {
weakSelf.testValue = ;
}; }
@end

再看下面的例子

#import "networkTool.h"

@implementation networkTool

//定一个block的网络请求
-(void)loadData:(void (^)(NSString * _Nonnull))finishedBlock{
//执行网络请求
//...
//完成回调返回
finishedBlock(@"jsonData");
} @end
@interface ViewController ()

@property (nonatomic,strong) networkTool *tool;

@end

@implementation ViewController

- (IBAction)button1Action:(id)sender {
self.tool=[networkTool new]; [self.tool loadData:^(NSString * _Nonnull jsonData) {
NSLog(@"接收到请求数据:%@",jsonData);
self.view.backgroundColor=[UIColor redColor];//此处没有循环引用
}]; } - (void)dealloc
{
NSLog(@"ViewController -- dealloc");
} @end

他们之间的引用关系 Block引用ViewController,ViewController引用networkTool,但是networkTool没有引用Block,如下图

Block循环引用问题(Objective-c)

下面这样会发生循环引用

@interface networkTool()
@property (nonatomic,copy) void(^finishedBlock2)(NSString*);
@end @implementation networkTool //定一个block的网络请求
-(void)loadData:(void (^)(NSString * _Nonnull))finishedBlock{
self.finishedBlock2 = finishedBlock;//小心block循环引用
//执行网络请求
//...
//完成回调返回
finishedBlock(@"jsonData");
} @end //===============ViewController================ @interface ViewController ()
@property (nonatomic,strong) networkTool *tool;
@end @implementation ViewController - (IBAction)button1Action:(id)sender {
self.tool=[networkTool new]; //block引起循环引用问题
[self.tool loadData:^(NSString * _Nonnull jsonData) {
NSLog(@"接收到请求数据:%@",jsonData);
self.view.backgroundColor=[UIColor redColor];
}]; } - (void)dealloc
{
NSLog(@"ViewController -- dealloc");
} @end

上面他们之间的引用关系 Block引用ViewController,ViewController引用networkTool,而且networkTool引用Block

解决方法:破坏这个闭合的环,如下

__weak typeof(self) weakSelf=self;
[self.tool loadData:^(NSString * _Nonnull jsonData) {
NSLog(@"接收到请求数据:%@",jsonData);
weakSelf.view.backgroundColor=[UIColor redColor];
}];
上一篇:iOS中Block循环引用的问题


下一篇:Block循环引用问题研究