IOS开发--循环引用问题,普通控件为何用weak,代理为何用weak,block内用到外面的东

全部的引用计数系统,都存在循环应用的问题。spa

例以下面的引用关系对象:代理

 a建立并引用到了对象b.指针

对象b建立并引用到了对象c.orm

对象c建立并引用到了对象b.对象

这时候b和c的引用计数分别是2和1。当a再也不使用b,调用release释放对b的全部权,由于c还引用了b,因此b的引用计数为1,b不会被释放。b不释放,c的引用计数就是1,c也不会被释放。今后,b和c永远留在内存中,形成内存浪费。这种状况,必须打断循环引用,经过其余规则来维护引用关系。
生命周期

那么普通控件为何要用weak:内存

以下图控制器中的View经过[self.view addSubview:btn];已经将Btn增长了强引用,因此不会被销毁,因此若是想把btn当作属性,没有必要在property中使用强引用浪费资源。资源

若是要用强引用也能够,由于在控制器销毁以后,控制器view也销毁了,因此btn销毁,不会形成强引用。it

代理为何要用weak以下图:io

假设把代理设置成strong那么就会执行语句UIScrollView*scrollView=[UIScrollView alloc]init];scrollView.delegate=self;(self表明控制器)后,

当控制器想要销毁时,控制器被一个强指针指着,而scrollView添加到控制器view中也被强指针指着,也没法销毁,那么它的delegate不会销毁。delegate指向控制器。形成了循环引用。把delegate变成weak:当控制器生命周期结束时,view随之销毁,内部子空间也随之销毁,delegate也就销毁了。


block内用到了外面的东西,须要转换成weak指针,不然会形成循环引用 以下图:

有这样一段代码,代码本意没必要理解:mail有一个block属性,那么block内有个邮件控制器须要设置代理。

ShareViewController内部强指针指向用Group,Group内部的items强指针指向mail对象,mail对象有个option属性(block),option内部用到了self也就是控制器,因此block(option是copy类型的)会用一个强指针指向self。注意:这里不和上边同样,不要被vc的代理(代理是weak的)所迷惑,是block强指针指向了self。形成了循环引用谁都没办法被销毁。

解决办法:使用:

__unsafe_unretained typeof(self) selfVc =self;

__unsafe_unretained HYShareViewController *selfVc =self;在block中让他对self只能进行弱引用。

或者把__unsafe_unretain改为__weak。(__unsafe_unretain和__weak的区别请见下一篇<OC语法--__unsafe_unretain、__strong、__weak、__autoreleasing这四种属性的做用>


    HYSettingItem *mail = [HYSettingArrowItemitemWithIcon:@"MailShare"title:@"邮件分享"destVcClass:nil];

    mail.option = ^{

       //不能发邮件

        if (![MFMailComposeViewControllercanSendMail])return;

        MFMailComposeViewController *vc = [[MFMailComposeViewControlleralloc]init];

        [vcsetSubject:@"会议"];

        [vc setMessageBody:@"今天下午开会吧"isHTML:NO];

        vc.mailComposeDelegate = selfVc;

       //显示控制器

        [selfVc presentViewController:vcanimated:YEScompletion:nil];

    };

 HYSettingGroup *group = [[HYSettingGroupalloc]init];

    group.items =@[sina, sms, mail];

    [self.dataaddObject:group];

}

相关文章
相关标签/搜索