`
dawuafang
  • 浏览: 1092024 次
文章分类
社区版块
存档分类
最新评论

ios block循环引用问题

 
阅读更多

ios开发中,开了ARC模式,系统自动管理内存,如果程序中用到了block就要注意循环引用带来的内存泄露问题了

这几天遇到一个问题,正常页面dismiss的时候是要调用dealloc方法的,但是我的程序就是不调用,研究了好久终于找到了问题出在哪里了

起初的代码如下:

- (void)getMyrelatedShops

{

[self.loadTimer invalidate];

self.loadTimer = [NSTimer scheduledTimerWithTimeInterval:0.1

target:discoverView

selector:@selector(loadWaiting)

userInfo:nil

repeats:YES];

sendedRequest = [[FindShopService sharedInstance] getMyRelatedShopsWithPageNO:pageNo

successBlock:^(TMRequest *request){

[self.loadTimer invalidate];

[self shopListRequestFinished:request];

}failedBlock:^(TMRequest *failedRequest){

[self.loadTimer invalidate];

[selfshopListRequestFailed:failedRequest];

}];

}

代码表面上看起来没有什么问题,但是细细研究就会发现两个问题

1、block中引用到self,self 被block retain,sendedRequest又retain了该block的一根拷贝

2.sendedRequest是在self类中定义赋值,因此是被self retain

因此就形成了循环引用,不会调用dealloc

还有一个问题,只要重复性 timer 还没有被 invalidated,target 对象就会被一直持有而不会被释放。因此当你使用 self 当作 target 时,你就不能期望在 dealloc 中 invalidate timer,因为在 timer 没有被invalidate 之前,dealloc 绝不会被调用。因此,需要找个合适的时机和地方来 invalidate timer,但绝不是在 dealloc 中。

修改如下

- (void)getMyrelatedShops

{

[self.loadTimer invalidate];

self.loadTimer = [NSTimer scheduledTimerWithTimeInterval:0.1

target:discoverView

selector:@selector(loadWaiting)

userInfo:nil

repeats:YES];

__unsafe_unretained FindShopVC *wfindShopVC = self;

sendedRequest = [[FindShopService sharedInstance] getMyRelatedShopsWithPageNO:pageNo

successBlock:^(TMRequest *request){

[wfindShopVC.loadTimer invalidate];

[wfindShopVC shopListRequestFinished:request];

}failedBlock:^(TMRequest *failedRequest){

[wfindShopVC.loadTimer invalidate];

[wfindShopVC shopListRequestFailed:failedRequest];

}];

}

这样就避免了循环引用,页面注销时就会调用dealloc方法了

关于block的详细解释可参考http://www.cnblogs.com/kesalin/archive/2013/04/30/ios_block.html


分享到:
评论

相关推荐

    ios-block循环引用的三种解决办法.zip

    block引用,解决办法,方便简单

    关于block的循环引用

    分析关于block的循环引用 详细了分析在ios开发中常见的错误,值得一看

    iOS MRC 下 block 循环引用问题实例讲解

    下面一段代码给大家介绍iOS MRC 下 block 循环引用问题  //注意此__block会复制一份指针出来 一次原始的指针如果置为nil的话,此处复制出来的指针还是野指针 __block __typeof(self)weakSelf = self; //__weak _...

    block的循环引用导致的内存泄露的示例及解决办法

    block的循环引用导致的内存泄露的示例及解决办法

    iOS面试中如何优雅回答Block导致循环引用的问题

    主要给大家介绍了iOS面试中关于如何优雅回答Block导致循环引用的问题的相关资料,文中通过图文介绍的非常相信,相信对大家具有一定的参考价值,需要的朋友们下面来一起看看吧。

    详解iOS 用于解决循环引用的block timer

    在上面的例子中,我可以看出,函数amount(其实是Block),的声明和调用在A类中,而实现部分在B类中。也就是说,B类实现了amount函数,但并没有权限调用,最终还是 由A类触发调用。我们称这样的机制为“回调”。意思...

    IOS 常见的循环引用总结

    IOS 常见的循环引用总结 介绍: 循环引用,指的是多个对象相互引用时,使得引用形成一个环形,导致外部无法真正是否掉这块环形内存。其实有点类似死锁。 举个例子:A->B->C->….->X->B ->表示强引用,这样的B的引用...

    iOS中的block是如何持有对象的

    文章中的代码都出自Facebook开源的用于检测循环引用的框架FBRetainCycleDetector,这是分析该框架文章中的最后一篇,也是笔者觉得最有意思的一部分。如果你希望了解FBRetainCycleDetector的原理可以阅读如何在iOS中...

    iOS利用Block逆向传值的方式详解

    在iOS通过代理逆向传值的方式详解一文中,分析了如何利用代理模式来逆向传值,其实还有一些其他的方式,如通知、Block等,相比较代理,我个人认为反而要简单些,但是需要处理好细节问题,如Block循环引用。...

    iOS面试 内存泄漏/基础知识

    第二种可能:block循环引用; 第三种可能:delegate循环引用; 第四种可能:NSTimer循环引用 第五种可能:非OC对象内存处理 第六种可能:地图类处理 第七种可能:大次数循环内存暴涨 追问一:非OC对象如何处理?

    Blocks编程要点[中文完整翻译版]- Blocks Programming Topics

    对了,使用Block要谨记别造成对象互相引用对方导致引用计数进入一个循环导致对象无法被释放。iOS 5.0之后的ARC也是无法解决该潜在的互相引用的问题的。所以写Block的时候要注意这点。因为Block往往在后台自动对一些...

    Blocks 编程要点

    对了,使用Block要谨记别造成对象互相引用对方导致引用计数进入一个循环导致对象无法被释放。iOS 5.0之后的ARC也是无法解决该潜在的互相引用的问题的。所以写Block的时候要注意这点。因为Block往往在后台自动对一些...

    ios-轻量级弹框下拉列表选择.zip

    一款轻量级的弹框列表选择,适用于有很多表单数据要填写的时候...代码本身并没有任何难点,完全是为了实用性,这里提供的类方法通过block传值访问外部变量也不会造成循环引用。其他的按钮颜色及定制化可随意自行修改。

    leetcode答案-iOS-:在网上找的一些iOS面试资料

    iOS面试题-----内存管理、自动释放池与循环引用 6、2019 iOS面试题-----Block原理、Block变量截获、Block的三种形式 7、2019 iOS面试题-----进程、线程、多进程、多线程、任务、队列、NSThread、GCD、...

    iOS开发技巧之WeakSelf宏的进化详解

    我们都知道在防止如block的循环引用时,会使用__weak关键字做如下定义: __weak typeof(self) weakSelf = self; 后来,为了方便,不用每次都要写这样一句固定代码,我们定义了宏: #define WeakSelf __weak typeof...

    ios-RJBadgeKit.zip

    3. 为防止循环引用,在badge的block里面用参数observer来代替self, RJBadgeKit对observer(即self.badgeController的self)进行了weak化处理并通过block回调参数传出 详细的使用示例请参考RJBadgeKit的Example工程...

Global site tag (gtag.js) - Google Analytics