block与GCD--40:块的循环引用

2023-11-22 08:30:13 浏览数 (1)

使用block时,很容易导致“保留环”

  • 第一种
代码语言:javascript复制
#import <Foundation/Foundation.h>
typedef void(^dosomethingBlock)(NSDictionary *dic);
@interface Student : NSObject
- (void)startBlock:(dosomethingBlock)block;
- (void)callBackData;
@end

#import "Student.h"
@interface Student()
@property (nonatomic,copy) dosomethingBlock block;
@end
@implementation Student
- (void)startBlock:(dosomethingBlock)block{
    if (block) {
        _block = block;
    }
}
- (void)callBackData{
    if (_block) {
        _block(@{@"key":@"value"});
    }
}
- (void)dealloc{
    NSLog(@"%s",__func__);
}
@end
---------------------
#import "ViewController.h"
#import "Student.h"
@interface ViewController ()
@property (nonatomic,strong) Student *stu;
@property (nonatomic,strong) NSDictionary *dic;
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
   _stu =  [[Student alloc]init];
    [_stu startBlock:^(NSDictionary *dic) {
        _dic = dic;
        NSLog(@"%@",self.dic[@"key"]);
    }];
    [_stu callBackData];
}
@end

运行程序发现student的delloc不会执行,因为在dosomethingBlock引用了ViewController,而Student又是ViewController属性,存在循环引用。 修改这个bug,只需要清掉其中一个引用即可

代码语言:javascript复制
_stu =  [[Student alloc]init];
    [_stu startBlock:^(NSDictionary *dic) {
        _dic = dic;
        NSLog(@"%@",self.dic[@"key"]);
        _stu = nil;
    }];
    
    [_stu callBackData];
  • 第二种
代码语言:javascript复制
typedef void(^dosomethingBlock)(NSDictionary *dic);
@interface Student : NSObject
- (void)startBlock:(dosomethingBlock)block;
- (void)callBackData;
@end

#import "Student.h"
@interface Student()
@property (nonatomic,copy) dosomethingBlock block;
@end
@implementation Student
- (void)startBlock:(dosomethingBlock)block{
    if (block) {
        _block = block;
    }
}
- (void)callBackData{
    if (_block) {
        _block(@{@"key":@"value"});
    }
}
- (void)dealloc{
    NSLog(@"%s",__func__);
}
@end

#import "ViewController.h"
#import "Student.h"
@interface ViewController ()
@property (nonatomic,strong) NSDictionary *dic;
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    Student *_stu =  [[Student alloc]init];
    [_stu startBlock:^(NSDictionary *dic) {
        _dic = dic;
        NSLog(@"%@--%@",self.dic[@"key"],_stu);
    }];
    
    [_stu callBackData];
}
@end

运行程序发现student的delloc不会执行,因为在dosomethingBlock引用了_stu自己,存在循环引用。 修改这个bug,只需要清掉其中一个引用即可

代码语言:javascript复制
- (void)callBackData{
    if (_block) {
        _block(@{@"key":@"value"});
        _block = nil;
    }
}

0 人点赞