解决NSTimer循环引用Retain Cycle问题

iOS开发中以下的情况会产生循环引用

  1. block
  2. delegate
  3. NSTimer

循环引用导致一些对象无法销毁,一定的情况下会对我们横须造成影响,特别是我们要在dealloc中释放一些资源额时候,本篇主要解决NSTimer引起的循环引用问题。

问题分析

主要由于NSTimer对象和调用NSTimer的视图控制器对象相互强引用了,其中NSTimer对视图控制器的引用发生在最后一个参数reapets为YES的时候,因为需要重复执行操作,所以需要强引用调用对象,那么解决办法有两点

  1. 让视图控制器对NSTimer的引用变成弱引用
  2. 让NSTimer对视图控制器的引用变成弱引用

分析一下两种方法,第一种方法如果控制器对NSTimer的引用改为弱引用,则会出现NSTimer直接被回收,所以不可使,因此我们只能从第二种方法入手

解决办法:使用一个NSTimer的Catagory,然后重写初始化方法,在实现中利用block,从而在调用的时候可以使用weakSelf在block执行任务,从而解除NSTimer对target(视图控制器)的强引用。

注:在iOS10中苹果为NSTimer类添加了带有block的初始化方法,解决了上述问题,实现的原理是一样的,但是我们要为了项目的各个系统版本的兼容,我们用分类增加了一个方法进行实现。

问题解决

我们为NSTimer添加Category方法

使用:

//添加计时器
-(void)addTiemrWeak{
__weak typeof(self)weakSelf = self;
self.timer = [NSTimer wk_scheduledTimerWithTimeInterval:1.0 repeats:YES handlerBlock:^void(void){
__strong typeof(weakSelf)strongSelf = weakSelf; //TO-DO...
}];
[[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
} //销毁计时器
-(void)destoryTimer{
if (self.timer) {
[self.timer invalidate];
self.timer = nil;
}
} -(void)dealloc{
[self destoryTimer];
}

实例下载WeakTimer-Timer

解决NSTimer循环引用Retain Cycle问题的更多相关文章

  1. 解决NSTimer循环引用

    NSTimer常见用法 @interface XXClass : NSObject - (void)start; - (void)stop; @end @implementation XXClass ...

  2. 用block解决nstimer循环引用

    大多数开发者可能都会这样来实现定时器.创建定时器的时候,由于目标对象是self,所以要保留此实例.然而,因为定时器是用实例变量存放的,所以实例也保留了定时器,这就造成了循环引用.除非调用stop方法, ...

  3. 避免在block中循环引用(Retain Cycle in Block)

    让我们长话短说.请参阅如下代码: - (IBAction)didTapUploadButton:(id)sender { NSString *clientID = @"YOUR_CLIENT ...

  4. NSTimer循环引用的几种解决方案

    前言 在iOS中,NSTimer的使用是非常频繁的,但是NSTimer在使用中需要注意,避免循环引用的问题.之前经常这样写: - (void)setupTimer { self.timer = [NS ...

  5. CADisplayLink、NSTimer循环引用解决方案

    前言:CADisplayLink.NSTimer 循环引用问题 ​ CADisplayLink.NSTimer会对Target产生强引用,如果target又对他们产生强引用,那么就会引发循环引用. @ ...

  6. 解决FastJson循环引用的问题

    temp 本来被循环引用,运行方法报错. 解决方法:对temp进行处理 SerializerFeature feature = SerializerFeature.DisableCircularRef ...

  7. Json.net对于导航属性的处理(解决对象循环引用)

    对于两张表A.B多对多的关系中,A的导航属性中有B,B的导航属性中有A,这样Json.net对A或者B对象序列化时会形成死循环 所以对于导航属性要加标签 首先在A.B实体类工程(Model)中引用Js ...

  8. 05解决flask循环引用的问题

    1, 什么是循环引用问题?为什么会导致循环引用? 1.1先讲是什么? 主文件中class类过多会导致主文件冗余,如下图,所以我们单独给class类一个文件,然后再引用它. 1.2再讲为什么? 主文件为 ...

  9. NSTimer循环引用的问题

    前言: 记得之前看过一个面试题问:ARC环境下的dealloc方法有什么用?问题解答是:代理指针置空,停止定时器timer,注销通知,释放掉实例变量.看着没什么问题,而且网上一收也是大概这样的答案.今 ...

随机推荐

  1. 对Vue.js $watch方法的理解

    博主最近对着vue.js的官方教程在自学vue.js,博主自幼愚钝,在教程中真的是好多点都不太理解,接下来要说的这个$watch方法就是其中一个不太理解的点了.咱们先来看一下对于$watch方法在vu ...

  2. php线程安全与非线程安全版的区别

    Thread Safe(线程安全)和 None Thread Safe(非线程安全) 背景: Linux/Unix系统采用多进程的工作方式,而Windows系统采用多线程的工作方式. CGI模式是建立 ...

  3. sass学习笔记 -- sass的四种编译方法

    sass的四种编译方法:(.scss) (一)ruby下的命令行编译 首先需要安装ruby,注意需勾选Add Ruby executables to your PATH选项,以添加环境变量. ruby ...

  4. 关于MFC中InvalidateRect()的思考与疑问

    先看一段代码: void CFeatureEdit_LinePolyDLG::DrawRectAll(int type){ CClientDC dc(this); //底框画笔 CPen penRec ...

  5. Power BI Embedded 与 Bot Framework 结合的AI解决方案

    最近最热门的话题莫过于AI了,之前我做过一片讲 BOTFRAMEWORK和微信 相结合的帖子 如何将 Microsoft Bot Framework 链接至微信公共号 我想今天基于这个题目扩展一下,P ...

  6. asp.net core mvc剖析:动作执行

    紧跟上一篇文章.通过路由和动作匹配后,最终会得到跟当前请求最匹配的一个ActionDescriptor,然后通过IActionInvoker执行动作. 我们先来看一下IActionInvoker如何得 ...

  7. javaWEB与cookie

    Cookie1. Http协议与Cookie(了解)  * Cookie是HTTP协议制定的!先由服务器保存Cookie到浏览器,再下次浏览器请求服务器时把上一次请求得到Cookie再归还给服务器  ...

  8. Linux ubuntu 安装gcc、g++、 pcre、zlib、ssl、nginx和该内存不能为written解决方法

    1.楼主也是第一次接触Linux  如果有错误的地方还请各位朋友指出.... 2.gcc.g++依赖库:sudo apt-get install build-essential,sudoapt-get ...

  9. iOS 应用关于弥补安全优化问题

    1.log输出会被中奖者截获,暴露信息,影响app得性能 在工程里面的pch文件加入以下代码 // 调试状态 #define LMLog(...) NSLog(__VA_ARGS__) #else / ...

  10. 【Egret】实现web页面操作PC端本地文件操作

    Egret 实现web页面操作PC端本地文件操作: http://edn.egret.com/cn/book/page/pid/181 //------------------------------ ...