第四十三篇、利用NSProxy解决NSTimer内存泄漏问题
问题描述:
用NSTimer来实现每隔一定时间执行制定的任务,例如最常见的广告轮播图。如果我们在 timerWithTimeInterval:1 target:self 中指定target为当前控制器,控制器则会被timer强引用,而控制器对timer也是强引用的。一般,我们终止定时器往往在界面销毁时,即dealloc方法中写 [_timer invalidate];。基于上面的分析,由于循环引用的存在,控制器永远也不会走dealloc方法,定时器会一直执行方法,造成内存泄露。
解决方案:
利用消息转发来断开NSTimer对象与视图之间的引用关系。初始化NSTimer时把触发事件的target替换成一个单独的对象,然后这个对象中NSTimer的SEL方法触发时让这个方法在当前的视图self中实现。
背景知识:
NSProxy:NSProxy 是一个抽象类,它接收到任何自己没有定义的方法他都会产生一个异常,所以一个实际的子类必须提供一个初始化方法或者创建方法,并且重载forwardInvocation:方法和methodSignatureForSelector:方法来处理自己没有实现的消息。
从类名来看是代理类,专门负责代理对象转发消息的。相比NSObject类来说NSProxy更轻量级,通过NSProxy可以帮助Objective-C间接的实现多重继承的功能。
代码:
#import <Foundation/Foundation.h> @interface XZHProxy : NSProxy
/**
* 代理的对象
*/
@property (nonatomic,weak)id obj;
@end
#import "XZHProxy.h" @implementation XZHProxy /**
这个函数让重载方有机会抛出一个函数的签名,再由后面的forwardInvocation:去执行
为给定消息提供参数类型信息
*/
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
NSMethodSignature *sig = nil;
sig = [self.obj methodSignatureForSelector:aSelector];
return sig;
} /**
* NSInvocation封装了NSMethodSignature,通过invokeWithTarget方法将消息转发给其他对象.这里转发给控制器执行。
*/
- (void)forwardInvocation:(NSInvocation *)anInvocation{
[anInvocation invokeWithTarget:self.obj];
}
@end
#import "ViewController.h"
#import "XZHProxy.h"
@interface ViewController ()
/**
*代理
*/
@property (nonatomic,strong)XZHProxy *proxy; /**
* 定时器
*/
@property (nonatomic,strong)NSTimer *timer; /**
* 计数
*/
@property (nonatomic,assign)NSInteger count; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.proxy = [XZHProxy alloc];
//作为当前控制器的代理
self.proxy.obj = self;
//target为代理
self.timer = [NSTimer timerWithTimeInterval: target:self.proxy selector:@selector(timerEvent) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
} - (void)timerEvent{
NSLog(@"%zd",self.count++);
} - (void)dealloc{
NSLog(@"----dealloc");
//释放计时器
[self.timer invalidate];
}
第四十三篇、利用NSProxy解决NSTimer内存泄漏问题的更多相关文章
- 利用NSProxy解决NSTimer内存泄漏问题
之前写过一篇利用RunTime解决由NSTimer导致的内存泄漏的文章,最近和同事讨论觉得这样写有点复杂,然后发现有NSProxy这么好用的根类,根类,根类,没错NSProxy与NSObject一样是 ...
- Android性能优化之利用Rxlifecycle解决RxJava内存泄漏
前言: 其实RxJava引起的内存泄漏是我无意中发现了,本来是想了解Retrofit与RxJava相结合中是如何通过适配器模式解决的,结果却发现了RxJava是会引起内存泄漏的,所有想着查找一下资料学 ...
- NSTimer内存泄漏
用NSTimer调用 timer = [NSTimer scheduledTimerWithTimeInterval:timerInterval target:self selector:@selec ...
- AutoDispose代替RxLifecycle优雅的解决RxJava内存泄漏问题
使用过Rxjava的小伙伴都知道,在使用RxJava时如果处理不当,很可能会产生内存泄漏的问题. 我们使用rxjava最大的原因是响应式编程使我们的异步操作代码变得很优雅,在Android中,也使线程 ...
- Python之路(第四十三篇)线程的生命周期、全局解释器锁
一.线程的生命周期(新建.就绪.运行.阻塞和死亡) 当线程被创建并启动以后,它既不是一启动就进入执行状态的,也不是一直处于执行状态的,在线程的生命周期中,它要经过新建(new).就绪(Ready).运 ...
- NSTimer内存泄漏导致控制器不调用dealloc
创建定时器会在一定的间隔后执行某些操作,一般大家会这样创建定时器,这样创建的定时,self对定时器有个引用,定时器对self也有个引用,造成了循环引用,最终造成了内存泄漏,如果定时器在做下载的操作就会 ...
- UWP开发入门(十三)——用Diagnostic Tool检查内存泄漏
因为.NET的垃圾回收机制相当完善,通常情况下我们是不需要关心内存泄漏的.问题人一但傻起来,连自己都会害怕,几个页面跳啊跳的,内存蹭蹭的往上涨,拉都拉不住.这种时候我们就需要冷静下来,泡一杯热巧克力. ...
- 使用Xcode和Instruments调试解决iOS内存泄漏
尽管iOS 5.0加入版本号之后ARC机制,由于相互引用关系是复杂的.内存泄漏可能仍然存在.于是,懂原理是非常重要的. 这里讲述在没有ARC的情况下,怎样使用Instruments来查找程序中的内存泄 ...
- 使用pidof/kill组合命令,变相解决mediaserver内存泄漏【转】
本文转载自:https://blog.csdn.net/lj402159806/article/details/78950384 在5.1系统下mediaserver有内存泄漏的问题,原因在于使用ca ...
随机推荐
- C语言高效编程的几招(绝对实用,绝对经典)
编写高效简洁的C语言代码,是许多软件工程师追求的目标.废话不说,走起! 第一招:以空间换时间 计算机程序中最大的矛盾是空间和时间的矛盾,那么,从这个角度出发逆向思维来考虑程序的效率问题 eg.字符串的 ...
- 【转】linux中的常见目录及文件
1. /proc目录 Linux 内核提供了一种通过 /proc 文件系统,在运行时访问内核内部数据结构.改变内核设置的机制.proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间.它以 ...
- python写的百度贴吧相册下载
突然想搞个这样的工具,写来写去都不知道在干嘛了,本来两个文件,现在整合在一起了. 乱得不行,懒得整理了,能用就行. 下载部分用了多线程,但是下载一个文件还是用的单线程,也就是没管http头的range ...
- phpStudy 2014的Apache虚拟主机配置
安装phpStudy直接百度下载,傻瓜式安装很简单,一直点击下一步即可,中途根据个人爱好设置WWW目录,我的设置在D盘根目录里. 打开虚拟主机配置,打开D:\phpStudy\Apache\conf下 ...
- 解决使用DevExpress开发错误:未将对象引用设置到对象的实例
在使用DevExpress是总是会出现一些状况.这次同事在他的机器上调试完成的代码发过来,却出现"未将对象引用设置到对象的实例"的错误,提示是Resources.resx的问题.另 ...
- delphi 立即显示提示
procedure TForm1.FormCreate(Sender: TObject); begin Application.HintPause:=0;//立即显示 Application.hi ...
- [Angular 2] Directive intro and exportAs
First, What is directive, what is the difference between component and directive. For my understandi ...
- 《赢在用户:Web人物角色创建和应用实践指南》阅读总结
本书针对创建人物角色的每一个步骤,包括进行定性.定量的用户研究,生成人物角色分类,使人物角色真实可信等进行了十分详细的介绍.而且,在人物角色如何指导总体商业策略.确定信息架构.内容和设计 ...
- 实例源码--Android简单音乐播放器源码
下载源码 技术要点: 1.本地音乐管理 2.在线音乐听歌.下载 3.音频流的解码 4. HTTP通信模块 5. Sqlite数据库 6. 源码带详细的中文注释 ...... 详细介绍: 1.本 ...
- C语言第一节 C语言程序与开发工具
开发工具的选择 可以用来写代码的工具:记事本.UltraEdit.Vim.Xcode等 选择Xcode的原因:苹果官方提供的开发利器.简化开发过程.有高亮显示功能 使用Xcode新建一个C程序的源代码 ...