探讨iOS block循环引用的问题

[复制链接]
109 27
-(void)gotoBVC
{
BViewConrollerViewController *bVC = [BViewConrollerViewController new];

bVC.myblock = ^(NSString *str) {
_textLab.text = str;
[self test];


};
[self presentViewController:bVC animated:YES completion:nil];
}
-(void)test
{
NSLog(@"test");
}
这段代码会不会造成循环引用呢?如果会 那应该怎么避免?
如果不会造成循环引用 那在哪种情况下才会造成循环引用呢? 希望大家多多发表自己的看法

举报 使用道具

回复

27 个评论

liuchun812  新手上路  发表于 2018-5-29 14:29:53  | 显示全部楼层
1.block体内用selfweak,不要self。
2.手动释放self,比如self是个vc,可以pop出去,是view,可以removefromesuperview。

比如你的例子,给个思路,首先bvc的block体内使用weakself,然后可以让bvc内部循环引用,self pop出去之后再触发下bvc的block

举报 使用道具

回复
大牛人啊  新手上路  发表于 2018-5-29 14:55:58  | 显示全部楼层
-(void)gotoBVC
{
    BViewConrollerViewController *bVC = [BViewConrollerViewController new];
   __strong ViewController *strongSelf = self;
    bVC.myblock = ^(NSString *str) {
      //异步执行,有可能执行到这里因为内存不做self被回收
        strongSelf.textLab.text = str;
        [self test];
    };
    [self presentViewController:bVC animated:YES completion:nil];
}

举报 使用道具

回复
viciousf  新手上路  发表于 2018-5-29 15:26:25  | 显示全部楼层
block 会循环引用是因为 block 也是一个对象 blockObject
blockObject 会把 block 大括号内部的所有东西保存为 blockObject 的属性

问题转变为两个对象间的循环引用
if (如果这个 block 被其他对象 A 当成强引用属性连接了 &&  block 大括号内部也有 A 的强引用)
那么这是一个循环引用
解决方法: 大括号内部对 A 进行弱引用

举报 使用道具

回复
troy852  新手上路  发表于 2018-5-29 16:11:37  | 显示全部楼层
最经典且基本的判断条件是看它们能不能构成彼此引用的闭环。
self只是推出了BVC,没有持有它,所以这不可能是个闭环,也不会造成内存泄漏。
当然导致内存泄漏的情况有很多种。

关于block与循环引用的问题,可以参考下面这篇博客

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

举报 使用道具

回复
skullcandy  新手上路  发表于 2018-5-29 16:18:46  | 显示全部楼层
我昨天也尝试做一个提前释放控制器的例子 大概思路就是window的根视图控制器是Navigation简称NC,aVC是NC的第一个子控制器,
从aVC push到bVC 再从bVC push到cVC ,cVC的block实现写在bVC中,点击cVC的按钮(用来释放bVC的,将NC的viewcontrollers中的bVC删掉,这时候这个数组只有aVC和cVC 然后 self.nav.viewcontrollers = 删除后bVC的数组),如此来说按道理bVC会被释放的,但是没有 ,估计是因为cVC的block持有bVC吧,但是当你在bVC中不写cVC的block实现,则bvc会被释放。所以我也想不到在什么情况下会被提前释放呢?

举报 使用道具

回复
hpy  新手上路  发表于 2018-5-29 17:05:33  | 显示全部楼层
你的self是vc,当然不存在提前释放了

block中self被提前释放的情况在实际开发中很少很少出现。

以至于我现编……没能编出来……

举报 使用道具

回复
wanjun575  新手上路  发表于 2018-5-29 17:13:07  | 显示全部楼层
不会,BViewConrollerViewController持有这个block,block持有self,而self并没有持有BViewConrollerViewController,所以并没有形成闭环,不会有循环引用问题

举报 使用道具

回复
oryiunei  新手上路  发表于 2018-5-29 17:38:52  | 显示全部楼层
谢谢 内容不能少于十个字

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

举报 使用道具

回复
orih  新手上路  发表于 2018-5-29 17:40:34  | 显示全部楼层
_textLab和_intNum是VC的属性,整个VC都可以访问。而num只是一个局部变量,不用__block修饰的话,block只是捕获num这个值而已;用__block修饰后,block捕获到num的地址。

举报 使用道具

回复
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

ios.irunthink.com
搜索
热搜: iOS swift 下拉刷新

图文热点

更多

开发教程

更多

客服中心

400-800 周一至周日 9:30-17:30 仅收市话费

关注我们

  • 微信扫描
  • 关注微信
关于我们
关于我们
友情链接
联系我们
帮助中心
精贴推荐
源码上传
注册登录
服务支持
资源下载
关注我们
官方微博
官方空间
快速回复 返回顶部 返回列表