首页
学习
活动
专区
圈层
工具
发布

iOS 如何解决 NSTimer 循环引用

前言 ---- 在使用 NSTimer,如果使用不得当特别会引起循环引用,造成内存泄露。所以怎么避免循环引用问题,下面我提出几种解决 NSTimer 的几种循环引用。 2....当你在 VC 的 dealloc 方法中销毁 timer,发现 VC 被 pop,VC 的 dealloc 方法没走,VC 在等 timer 释放才走 dealloc,timer 释放在 dealloc...,然后在 dealloc 方法中执行 NSTimer 的销毁,相对的 PFTimer 也会进行销毁了。...使用很简单,但是要注意两点: 避免 block 的循环引用,使用 __weak 和 __strong 来避免 在持用 NSTimer 对象的类的方法中 -(void)dealloc 调用 NSTimer...在传入参数时要通过 copy 方法,将 block 拷贝到"堆区",否则等到稍后要执行它的时候,该 blcok 可能已经无效了。

1.8K30
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    iOS NSTimer不走的问题

    iOS NSTimer不走的问题 背景 这个版本上线后,突然发现埋点数据直线下降,调试后发现是定时器上传的方法没有走,但是定时器的方法本期并没有修改过。...原因 iOS是通过runloop作为消息循环机制,主线程默认启动了runloop,可是自线程没有默认的runloop,因此,我们在子线程启动定时器是不生效的。...解决方法:在子线程启动一下runloop即可 - (BOOL)initTimer() { self.uploadTimer = [NSTimer scheduledTimerWithTimeInterval...,有两点收获, timer在iOS开发中经常使用,在很多博客中都看到关于timer要注意的地方也很多,通常是内存管理,timer启动相关,但是在开发中,如果没有真正遇到问题,没有“疼”在自己身上,就自己注意的就不够...参考 IOS定时器操作和NSTimer的各种坑

    77721

    iOS NSTimer不走的问题

    iOS NSTimer不走的问题 背景 这个版本上线后,突然发现埋点数据直线下降,调试后发现是定时器上传的方法没有走,但是定时器的方法本期并没有修改过。...原因 iOS是通过runloop作为消息循环机制,主线程默认启动了runloop,可是自线程没有默认的runloop,因此,我们在子线程启动定时器是不生效的。...解决方法:在子线程启动一下runloop即可 - (BOOL)initTimer() { self.uploadTimer = [NSTimer scheduledTimerWithTimeInterval...,有两点收获, timer在iOS开发中经常使用,在很多博客中都看到关于timer要注意的地方也很多,通常是内存管理,timer启动相关,但是在开发中,如果没有真正遇到问题,没有“疼”在自己身上,就自己注意的就不够...参考 IOS定时器操作和NSTimer的各种坑

    1.6K31

    系统框架--52:NSTimer会保留其目标对象

    NSTimer 计时器要和runloop相关联,runloop会触发任务。创建NSTimer时,可以将其“预先安排”在当前的runloop中,也可以创建好,然后再由开发人员自己调度。...也就是合适的时候调用end方法。然而,合适的时机很难找到。假如这是一个验证码倒计时程序,你可以在倒计时结束时调用end方法。...但是你不能确定用户一定会等倒计时结束才返回到上一级页面.或许你想在dealloc方法中使定时器失效,那你就太天真了。此时定时器还保留着当前控制器,此方法是不可能调用的,因此会出现内存泄漏。...或许在倒计时程序中,你可以重写返回方法,先调用end再返回,但这不是一个好主意 这里采用block块的方法为NSTimer增加一个分类,具体细节看代码(程序员最好的语言是代码)。...iOS10中,定时器的API新增了block方法,实现原理和这一样,只不过我这里用的是分类,而系统是在原始类中直接添加方法,最终的行为是一致的 #import "Student.h" @implementation

    50710

    object-c编程tips-timer「建议收藏」

    你可能会说在dealloc中调用invalidate,可是必须明确dealloc根本就不会调用,当然viewDidDisappear也一样不会被调用。...它保留的是类对象,因此也就不会有什么问题。 它传入要运行的block, 然后在回调函数中通过userInfo得到block,并运行。 改进: 这个已经是一个非常大的改进了。...当然能够在block中使用weak_self的方式避免循环引用,可是写起代码来总是有些不顺手。并且还必需要外部使用者显式的进行。 于是非常easy想到。应该封装到一个专门的LPTimer类中。...外部的使用者能够将LPTimer看成是一个普通的对象即可,持有它也不会有什么问题。 LPTimer保留一个弱引用指向外部的使用者。在时间到timer触发的时候,会先调到NStimer的block中。...必须注意释放NStimer对象,在LPTimer释放的时候调用NSTimer的invalidate方法。

    49110

    iOS APP运行时Crash自动修复系统

    与此同时,如果NSTimer是无限重复的执行一个任务的话,也有可能导致target的selector一直被重复调用且处于无效状态,对app的CPU,内存等性能方面均是没有必要的浪费。...所以,很有必要设计出一种方案,可以有效的防护NSTimer的滥用问题。...3.4.2 NSTimer crash 防护方案 上面的分析可见,NSTimer所产生的问题的主要原因是因为其没有再一个合适的时机invalidate,同时还有NSTimer对target的强引用导致的内存泄漏问题...那么解决NSTimer的问题的关键点在于以下两点: NSTimer对其target是否可以不强引用 是否找到一个合适的时机,在确定NSTimer已经失效的情况下,让NSTimer自动invalidate...由上图流程可知,当NSTimer的回调函数fireProxyTimer:被执行的时候,会自动判断原target是否已经被释放,如果释放了,意味着NSTimer已经无效,此时如果还继续调用原有target

    3.8K1713

    iOS从timer释放问题看内存管理

    在iOS的开发中,如果使用NSTimer做定时器,一定要在合适的时机销毁这个定时器,不然可能导致内存得不到释放。原因就是循环引用。...,timer还在一直跑着,因为dealloc方法的调用得在timer释放之后,而timer的释放在dealloc里,相互等待,这样就永远得不到释放了。...也就是 self ),循环引用了,也就是 NSTimer 强引用了 self ,导致 self 一直不能被释放掉,所以也就走不到 self 的 dealloc 里。...好的,从这个问题我们思考iOS的内存管理: 现在的iOS开发基本都是ARC的,ARC也是基于引用计数的,只是编译器在编译时期自动在已有代码中插入合适的内存管理代码(包括 retain、release、...如上或常在block中使用的: __weak 和 __block

    2K20

    浅析 NSTimer 和 CADisplayLink 内存泄漏

    以 UITableViewCell 为例: 一、在 Cell 中直接使用 NSTimer 首先我们按照常规做法,直接在 UITableView 的 Cell 上添加相应的 NSTimer, 并使用 scheduledTimer...但是,从上面的 demo 中看出,在 UITableViewCell 的 dealloc 方法中调用 invalidate 方法,并没有解决问题。...由此会想到另外一种方案,在 ViewController 的 dealloc 方法中调用 invalidate 方法,这种方案能解决问题,但是总感觉别扭。 [图片上传失败......(image-d0e3cd-1528529178817)] 如图所示,在开发中,如果创建定时器只是简单的计时,不做其他引用,那么 timer 对象与 myClock 对象循环引用的问题就可以避免(即省略...所以我们要做的是在向 myClock 对象发送 dealloc 消息前在给 timer 发送 invalidate 消息,从而避免本末倒置的问题。

    1.9K10

    回发或回调参数无效。在配置中使用 或在页面中使用

    大家好,又见面了,我是你们的朋友全栈君。 回发或回调参数无效。...这两天写程序总是遇到相似的程序在不同页面,出现不一样的结果。以下是今天出现的问题: 回发或回调参数无效。...3、如果页面含有 DropDownList 或 ListBox这样的控件,可能以下原因造成: 3.1 在下拉菜单中使用ajax,常见于省市联动菜单,可能是由于在aspx页面赋给了下拉菜单初始Item...在配置中使用 enableEventValidation=true或在页面中使用 启用了事件验证。 回发或回调参数无效。...3、如果页面含有 DropDownList 或 ListBox这样的控件,可能以下原因造成: 3.1 在下拉菜单中使用ajax,常见于省市联动菜单,可能是由于在aspx页面赋给了下拉菜单初始Item

    2.4K30

    解决innerHtml 在Jquery上使用无效果的问题

    ' + loadTime + 'ms'); innerHTML在JQuery中使用的话是无效果的, JQuery提供了三种方法实现指定标签赋内容:.html(),.val(),.text()。...三种方法区别具体: .html()用为读取和修改元素的HTML标签 对应js中的innerHTML .html()是用来读取元素的HTML内容(包括其Html标签), .html()方法使用在多个元素上时...对应js中的innerText text()用来读取元素的纯文本内容,包括其后代元素;.text()方法不能使用在表单元素上 .val()用来读取或修改表单元素的value值 .val()是用来读取表单元素的..."value"值,.val()只能使用在表单元素上 关于三者的区别 .val()方法和.html()相同,如果其应用在多个元素上时,只能读取第一个表单元素的"value"值,但是.text()和他们不一样....html(),.text(),.val()都可以使用回调函数的返回值来动态的改变多个元素的内容。**

    1.6K10

    iOS常见的内存问题——循环引用

    全局的 Block 比较简单,凡是没有引用到 Block 作用域外面的参数的 Block 都会放到全局内存块中,在全局内存块的 Block 不用考虑内存管理问题。...(放在全局内存块是为了在之后再次调用该 Block 时能快速反应,当然没有调用外部参数的 Block 根本不会出现内存管理问题)。...所以 Block 的内存管理出现问题的,绝大部分都是在堆内存中的 Block 出现了问题。...这里需要注意的是,在调用方的 dealloc 中一定要调用 timer 的 invalidate 方法,因为如果这里不清理 timer,这个调用方 dealloc 被释放后,消息转发就找不到接收方了,就会...总结 在App开发中的内存问题往往是最难发现而且最难排查解决的问题,因此我们需要在开发之初就要对代码进行审查,针对上面提出的几个问题要多加关注,与此同时,我们还需要利用评测工具来助力,Instruments

    2.2K10

    ARC 环境下 dealloc 的使用误区

    在MRC时代,我们需要在 dealloc中做很多,比如释放对象,如今我们已经进入ARC时代,对于普通对象的释放,系统已经帮我们做好了;是不是我们就再也不用担心内存问题了呢?答案是否定的 。...一.dealloc 的使用 a. 什么情况下会调用呢? 当对象的引用计数为0,系统会自动调用dealloc方法,回收内存。...二.dealloc 误区 我们在开发过程中,用到dealloc,却因不会意识得到对象的引用计数是不是为0,dealloc到底走了没走,因而导致内存暴增,还会遇到很多奇怪的问题。...controller中使用了计时器 NSTimer 使用后没有销毁 导致循环引用 self.playerTimer = [NSTimerscheduledTimerWithTimeInterval:1target...根据上面的方法排查: 最后发现自己在delegate用的不是week而是strong。顿时感觉自己好傻! ? 自己挖的坑 总结:再使用dealloc时,最好先看一下该方法有没有调用!

    1.1K40

    自欺欺人的使用 NSTimer 销毁

    ] addTimer:self.timer forMode:NSRunLoopCommonModes]; 以上两种方式都是在主线程上创建的,如果在子线程创建的timer,加入到runloop则需要手动开启...[self.timer invalidate]是唯一的方法将定时器从循环池中移除 - (void)dealloc { // 自欺欺人的写法,永远都不会执行到,除非你在外部手动invalidate...也就是说 NSTimer 强引用了 self ,self的全局变量 NSTimer 又使 self 强引用了 NSTimer,导致 self 一直不能被释放掉,所以也就走不到 self 的 dealloc...是由于我们的 self 和 weakSelf 都是指针指向控制器,控制器的dealloc需要timer的销毁才调用。同样造成相互强引用。...(10.0), watchos(3.0), tvos(10.0)); 自定义分类创建NSTimer,适用于iOS 10以前 原理等同于以上方法,把 target 转换为 NSTimer 自身然后把控制器的定时器方法在

    2.1K70

    Runtime运用:埋点统计

    对应的返回上一个界面的方式是pop和dismiss,一般在pop或者dismiss方法调用之后,随后就会调用dealloc方法,将UIViewController内存情况,内存得到释放,如果无法调用dealloc..."), @selector(ht_dealloc)); } NSObject的load方法,在每个class导入的时候,只要实现了这方法,就会调用而且只调用一次这个方法。...在load方法中,将UIViewController的生命周期里的几个method都通过method swizzling替换成我们自定义的方法,在自定义的方法中进行埋点,从而达到统计和监测的目的。...四、内存泄漏 因为UIViewController得不到释放而造成内存泄漏的情景有三种 NSTimer NSTimer:一方面,NSTimer经常会被作为某个类的成员变量,而NSTimer初始化时要指定...Delegate Delegate:声明Delegate要用weak;当delegate指向的对象销毁后,delegate = nil;如果用assign,可以解决循环引用的问题,但是可能会出现野指针

    1.3K20

    关于 循环引用问题

    NSTimer 因为NSTimer 的 target 对传入的参数都是强引用,所以当类具有NSTimer类型的成员变量,并且需要反复执行计时任务时容易造成循环引用。...解决方法(手动释放): [_timer invalidate]; _timer = nil; 注意:有人把销毁_timer的方法放在dealloc里,感觉就是自我安慰,循环引用造成不调用dealloc...方法,放在viewDidDisappear中又限制太死,最好的方法为(NSTimer的类别): @interface NSTimer (EXBlock) + (NSTimer *)ex_scheduledTimeWithTimeInterval...{ [_timer invalidate]; } 原理:在NSTimer类别定义的类方法中,有一个类型为块的参数(定义的块位于栈上,为了防止块被释放,需要调用copy方法,将块移到堆上),__...使用:使用pods或者下载导入项目,运行,通过提示框和控制器台打印来提示哪里有内存泄漏的问题。 ?

    3.9K20

    自欺欺人的使用 NSTimer 销毁

    ] addTimer:self.timer forMode:NSRunLoopCommonModes]; 以上两种方式都是在主线程上创建的,如果在子线程创建的timer,加入到runloop则需要手动开启...[self.timer invalidate]是唯一的方法将定时器从循环池中移除 - (void)dealloc { // 自欺欺人的写法,永远都不会执行到,除非你在外部手动invalidate...也就是说 NSTimer 强引用了 self ,self的全局变量 NSTimer 又使 self 强引用了 NSTimer,导致 self 一直不能被释放掉,所以也就走不到 self 的 dealloc...是由于我们的 self 和 weakSelf 都是指针指向控制器,控制器的dealloc需要timer的销毁才调用。同样造成相互强引用。...(10.0), watchos(3.0), tvos(10.0)); 自定义分类创建NSTimer,适用于iOS 10以前 原理等同于以上方法,把 target 转换为 NSTimer 自身然后把控制器的定时器方法在

    60260
    领券