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
分享到:
相关推荐
block引用,解决办法,方便简单
分析关于block的循环引用 详细了分析在ios开发中常见的错误,值得一看
下面一段代码给大家介绍iOS MRC 下 block 循环引用问题 //注意此__block会复制一份指针出来 一次原始的指针如果置为nil的话,此处复制出来的指针还是野指针 __block __typeof(self)weakSelf = self; //__weak _...
block的循环引用导致的内存泄露的示例及解决办法
主要给大家介绍了iOS面试中关于如何优雅回答Block导致循环引用的问题的相关资料,文中通过图文介绍的非常相信,相信对大家具有一定的参考价值,需要的朋友们下面来一起看看吧。
在上面的例子中,我可以看出,函数amount(其实是Block),的声明和调用在A类中,而实现部分在B类中。也就是说,B类实现了amount函数,但并没有权限调用,最终还是 由A类触发调用。我们称这样的机制为“回调”。意思...
IOS 常见的循环引用总结 介绍: 循环引用,指的是多个对象相互引用时,使得引用形成一个环形,导致外部无法真正是否掉这块环形内存。其实有点类似死锁。 举个例子:A->B->C->….->X->B ->表示强引用,这样的B的引用...
文章中的代码都出自Facebook开源的用于检测循环引用的框架FBRetainCycleDetector,这是分析该框架文章中的最后一篇,也是笔者觉得最有意思的一部分。如果你希望了解FBRetainCycleDetector的原理可以阅读如何在iOS中...
在iOS通过代理逆向传值的方式详解一文中,分析了如何利用代理模式来逆向传值,其实还有一些其他的方式,如通知、Block等,相比较代理,我个人认为反而要简单些,但是需要处理好细节问题,如Block循环引用。...
第二种可能:block循环引用; 第三种可能:delegate循环引用; 第四种可能:NSTimer循环引用 第五种可能:非OC对象内存处理 第六种可能:地图类处理 第七种可能:大次数循环内存暴涨 追问一:非OC对象如何处理?
对了,使用Block要谨记别造成对象互相引用对方导致引用计数进入一个循环导致对象无法被释放。iOS 5.0之后的ARC也是无法解决该潜在的互相引用的问题的。所以写Block的时候要注意这点。因为Block往往在后台自动对一些...
对了,使用Block要谨记别造成对象互相引用对方导致引用计数进入一个循环导致对象无法被释放。iOS 5.0之后的ARC也是无法解决该潜在的互相引用的问题的。所以写Block的时候要注意这点。因为Block往往在后台自动对一些...
一款轻量级的弹框列表选择,适用于有很多表单数据要填写的时候...代码本身并没有任何难点,完全是为了实用性,这里提供的类方法通过block传值访问外部变量也不会造成循环引用。其他的按钮颜色及定制化可随意自行修改。
iOS面试题-----内存管理、自动释放池与循环引用 6、2019 iOS面试题-----Block原理、Block变量截获、Block的三种形式 7、2019 iOS面试题-----进程、线程、多进程、多线程、任务、队列、NSThread、GCD、...
我们都知道在防止如block的循环引用时,会使用__weak关键字做如下定义: __weak typeof(self) weakSelf = self; 后来,为了方便,不用每次都要写这样一句固定代码,我们定义了宏: #define WeakSelf __weak typeof...
3. 为防止循环引用,在badge的block里面用参数observer来代替self, RJBadgeKit对observer(即self.badgeController的self)进行了weak化处理并通过block回调参数传出 详细的使用示例请参考RJBadgeKit的Example工程...