美文网首页程序员iOS Developer
iOS中delegate和IBOutlet为何使用弱引用

iOS中delegate和IBOutlet为何使用弱引用

作者: Mad_Mark | 来源:发表于2017-01-11 10:52 被阅读409次

    有时候一些理所当然的事,一细想之后才发现,没那么简单。

    问:为何delegate要用weak引用,而不是strong?
    答:避免循环引用,防止内存泄漏!

    好!假设有AVC和BVC两个ViewController,AVC推出BVC,在推出BVC之前,AVC将自己设为BVC的delegate。代码看起来是这样的:

    // AVC.m
    
    - (void)pushBVC
    {
        BVC *bvc = [BVC new];
        bvc.delegate = self;
        [self.navigationController pushViewController: bvc animated:YES];
    }
    

    在这样的环境下,如果bvc的delegate引用如果是strong,是否会造成循环引用?

    // BVC.h
    
    @property (nonatomic, strong) id<BVCDelegate> delegate;
    

    来分析一下。bvc的delegate指向了AVC的实例,是个强引用。但是,AVC实例并没有引用bvc这块对象,只是将bvc压到navigationController的栈里了。所以并没有循环引用。

    那为什么我们平时都用weak而不用strong呢?

    一、就这种情况下而言,如果使用了strong,avc的引用计数+1。然而在栈里面,bvc一定是比avc先释放的,bvc一释放,引用计数又减1了。也就是说这个引用计数+1的操作一点意义都没有。bvc在,avc一定在。

    二、再说说UITableView的delegate和datasource,这里如果改成strong引用,对不起,循环引用!为什么,因为这个tableview确确实实是当前vc所持有的,是strong引用了的,而这时如果tableview再strong引用自己的delegate or datasource,肯定循环引用。所以这种情况下,必须用weak。

    三、那IBOutlet呢,一般都是weak,能用strong么?

    viewfromxib.png

    看图说话,我们创建VC的同时创建的xib,等同于我们操作的self.view, self对view是强引用的,所有这些子view又都在self.view.subviews的数组中,也就是已经强引用这些子view了,所以我们在IBOutlet的时候无需再用strong,weak就行。看下图:


    subviewlist.png

    如果你用了strong,引用计数一定还会再+1,这时子视图可能就会释放不掉,你需要自己在正确的时机释放。

    还有一种情况,你的xib中除了原先的view之外,又创建了一个viewB,这个时候viewB没有被任何人引用,和self.view也没有关系,也不在self.view.subviews中。那么你在IBOutlet链接这个viewB的时候就必须用strong,而不是weak了。

    如果有不正确的地方欢迎指出。

    相关文章

      网友评论

        本文标题:iOS中delegate和IBOutlet为何使用弱引用

        本文链接:https://www.haomeiwen.com/subject/kenkbttx.html