iOS进阶指南iOS Developer程序员

iOS关于Block的循环引用问题小结

2016-06-27  本文已影响1195人  当阳桥

今天刚好是新工作入职的整一个月,趁今天有点时间,总结一下一个月前面试出现的一个关于Block循环引用的问题,当时面试一家上市公司,他妈的三个人面试哥们儿我一个,问的哥是一脸懵逼啊。。。通过面试的确可以发现之前的积累的知识有很多漏洞,后面有时间慢慢补充。。。

有个问题当我们第一次接触block的时候一定会听到block要注意防止循环引用啊!!!从此菜鸟们就记住了看见block就来个weak。然而一直在用中来没有去关注,他妈的有些时候还是可以不用weak的。。。

下面大致是面试时候的问题:block在什么情况下会出现循环引用?
答:比如控制器在使用一个Block,这个block又在使用控制器就会出现循环引用。。。(我自以为答的很完美)
后面那个哥们儿又加了一句:如果控制器没有通过一个属性来strong一个Block,那么还会不会出现循环引用?。。。他既然这样问,其实哥的潜意识是觉得不会的,但是从来没有检验过就没有直面回答,害怕打错了,就把话题绕开了。

这个结放在心里很久了,今天做了一个demo测试了一下。

下面是大概代码:

VC1

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UIButton *btn =  [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
    btn.backgroundColor = [UIColor redColor];
    [self.view addSubview:btn];
    
    [btn addTarget:self action:@selector(present) forControlEvents:UIControlEventTouchUpInside];
    
}

- (void)present{
    SecViewController *vc = [[SecViewController alloc] init];
    
    [self presentViewController:vc animated:YES completion:nil];

}

@end

VC2

#import "TestView.h"
@interface SecViewController ()
@property (nonatomic,strong) TestView *testView;//如果不加这一句后面可以不用weak来引用block,控制器同样可以释放
@end
@implementation SecViewController

- (void)dealloc{
    
    NSLog(@"------dealloc------");
}
- (void)viewDidLoad {
    [super viewDidLoad];

    TestView *view =  [[TestView alloc] init];
    
    __weak typeof(self)weakSelf = self;
    view.block = ^(int a){
        
        [weakSelf test];
        
    };
    
    view.block(10);

    self.testView = view;//如果没有这一句__weak typeof(self)weakSelf = self可以去掉也不会出现循环引用,控制器可以释放,如果加了这个那么前面必须用 __weak typeof(self)weakSelf = self来替带
    
    UIButton *btn =  [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
    btn.backgroundColor = [UIColor redColor];
    [self.view addSubview:btn];
    
    [btn addTarget:self action:@selector(pop) forControlEvents:UIControlEventTouchUpInside];
}

- (void)pop{
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)test{
    
    NSLog(@"--------------test");
}

View:

typedef void (^Block) (int a);

@interface TestView : UIView

@property (nonatomic,copy) Block block;

@end
上一篇下一篇

猜你喜欢

热点阅读