IOS开发-循环引用有关问题,普通控件为什么用weak,代理为什么用weak,block内用到外面的东西要用_weak

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

所有的引用计数系统,都存在循环应用的问题。

例如下面的引用关系对象:

 a创建并引用到了对象b.

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

对象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销毁,不会造成强引用。IOS开发-循环引用有关问题,普通控件为什么用weak,代理为什么用weak,block内用到外面的东西要用_weak

代理为什么要用weak如下图:

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

当控制器想要销毁时,控制器被一个强指针指着,而scrollView添加到控制器view中也被强指针指着,也无法销毁,那么它的delegate不会销毁。delegate指向控制器。造成了循环引用。把delegate变成weak:当控制器生命周期结束时,view随之销毁,内部子空间也随之销毁,delegate也就销毁了。IOS开发-循环引用有关问题,普通控件为什么用weak,代理为什么用weak,block内用到外面的东西要用_weak


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];

}

IOS开发-循环引用有关问题,普通控件为什么用weak,代理为什么用weak,block内用到外面的东西要用_weak