NSTimer循环引用的问题
前言:
记得之前看过一个面试题问:ARC环境下的dealloc方法有什么用?问题解答是:代理指针置空,停止定时器timer,注销通知,释放掉实例变量。看着没什么问题,而且网上一收也是大概这样的答案。今天算是被实实在在的坑了一把,唉,其实说是被坑不如说是自己对定时器NSTimer没有一个足够的认识,我们总是习惯性的看着别人给好的答案而懒得去看API文档仔细分析。
定时器NSTimer:
最近做的一个公司项目有一个需求,当你进入到某一个视图控制器中定时器timer开始启动并在1秒内触发timerAction:方法。然后在视图控制器中销毁的时候停止定时器。于是乎:
>
self.mytimer = [NSTimer scheduledTimerWithTimeInterval:1 target:weakSelf selector:@selector(timerAction:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.mytimer forMode:NSRunLoopCommonModes];
> #**并且在dealloc方法里面销毁定时器**
-(void)dealloc
{
[self.mytimer invalidate];
// 别忘了把定时器置为nil,否则定时器依然没有释放掉的
self.mytimer = nil;
}
一切看起来都是很安好没有什么不妥的地方,但是平静的湖面上就隐藏者巨大的风险。当跳转到其他页面的时候定时器还一直在输出,这时就纳闷了。在dealloc的打断点发现dealloc根本不执行,想想自己对定时器的处理是根据面试题中的答案难不成是自己在哪里犯二了。后来仔细一分析问题的关键在于timer对target进行了强引用,在这里也就是对self进行了强引用,导致页面要销毁的时候不会执行dealloc方法。既然是被强引用了就应该使用__weak,所以:
__weak typeof(self) weakSelf = self;
self.mytimer = [NSTimer scheduledTimerWithTimeInterval:1 target:weakSelf selector:@selector(timerAction:) userInfo:nil repeats:YES];
但是有没使用__weak修饰的差别在于self有没被释放掉而已,self则一直被timer强引用着。
最后发现一个很简单的解决方法就是在
-(void)viewDidDisappear:(BOOL)animated或者
-(void)viewWillDisappear:(BOOL)animated 中停止定时器停止并把定时器置为nil就可以解决问题。
与其说是自己被坑不如说是对它认识的不足,对网上很多人的答案都坚信不疑,才会使自己一开始就陷入错误
NSTimer循环引用的问题的更多相关文章
- 解决NSTimer循环引用Retain Cycle问题
解决NSTimer循环引用Retain Cycle问题 iOS开发中以下的情况会产生循环引用 block delegate NSTimer 循环引用导致一些对象无法销毁,一定的情况下会对我们横须造成影 ...
- 解决NSTimer循环引用
NSTimer常见用法 @interface XXClass : NSObject - (void)start; - (void)stop; @end @implementation XXClass ...
- CADisplayLink、NSTimer循环引用解决方案
前言:CADisplayLink.NSTimer 循环引用问题 CADisplayLink.NSTimer会对Target产生强引用,如果target又对他们产生强引用,那么就会引发循环引用. @ ...
- 用block解决nstimer循环引用
大多数开发者可能都会这样来实现定时器.创建定时器的时候,由于目标对象是self,所以要保留此实例.然而,因为定时器是用实例变量存放的,所以实例也保留了定时器,这就造成了循环引用.除非调用stop方法, ...
- NSTimer循环引用的几种解决方案
前言 在iOS中,NSTimer的使用是非常频繁的,但是NSTimer在使用中需要注意,避免循环引用的问题.之前经常这样写: - (void)setupTimer { self.timer = [NS ...
- iOS 循环引用解决方案
一.BLOCK 循环引用 一般表现为,某个类将block作为自己的属性变量,然后该类在block的方法体里面又使用了该类本身.构成循环引用. // 定义 block 的时候,会对外部变量做一次 cop ...
- iOS 里面 NSTimer 防止 循环引用
使用NSTimer的类 #import "TBTimerTestObject.h" #import "TBWeakTimerTarget.h" @interfa ...
- NSTimer定时器进阶——详细介绍,循环引用分析与解决
引言 定时器:A timer waits until a certain time interval has elapsed and then fires, sending a specified m ...
- NSTimer的循环引用
在日常开发中想到会引起循环引用的一般比较容易想起的是 1.delegate 2.block 今天要说的就是另外一个,NSTimer 这个比较容易会被忽略掉 简单的说就是创建timer为成员变量的时候t ...
随机推荐
- .Net Core 项目区域请求设置
.net core 和asp.net MVC区域请求有个区别,这里重点记录一下 asp.net MVC 区域请求直接是/区域名称/控制名称/方法名称,其他不需要设置任何东西,而Core 项目这样请求路 ...
- PHP获取对象的纯数字属性
php的对象属性 我们知道获取php的对象属性用箭头: echo $obj->name; 如果属性名是一个变量,那么可以用: $var = 'name'; echo $obj->$var; ...
- 洛谷P2762 太空飞行计划问题(最小割)
传送门 我们可以把实验放在左边,仪器放在右边,点有点权,然后连对应的有向边,就是求一个最大权闭合图,可以转化为最小割来做(关于这具体是个啥……可以百度胡伯涛<最小割模型在信息学竞赛中的应用> ...
- linux系统安全及应用——PAM安全认证
一.PAM认证模块介绍 PAM认证模块,叫做可插拔式的认证模块.一项重要的功能就是为了加强su命令的使用控制,可以借助于PAM认证模块,只允许极个别用户使用su命令进行切换.PAM提供了对所有服务进行 ...
- JDBC_设计架构_驱动类加载_建立Connection_效率测试
JDBC(Java DataBase Connection) 访问数据库流程:驱动管理器--连接数据库--sql语句--结果集 装载mysql驱动 Class.forName("com.jd ...
- Vue 环境配置
最开始摸element的时候,像盲人摸象,完全没有头绪. https://panjiachen.github.io/vue-element-admin-site/zh/guide/essentials ...
- 洛谷 P1372 又是毕业季I
可能所有的数论题都是这样玄学.... 题目链接:https://www.luogu.org/problemnew/show/P1372 这道题通过暴力的枚举可以发现是不可做的(当然我也不会做) 然后就 ...
- 【Java】qatools.properties
Link: https://github.com/qatools/properties 今天在GitHub上看到一个Java库,能方便帮助读取properties的配置文件. 具体使用可以参考上面的链 ...
- Android 简单适配器(SimpleAdapter)
1.介绍 2.简单适配器的实现方法 3.XML文件 (1)主页面布局 <?xml version="1.0" encoding="utf-8"?> ...
- Android 开源项目使用指南
1.日历项目 https://blog.csdn.net/iamchan/article/details/81214498