利用NSProxy解决NSTimer内存泄漏问题
之前写过一篇利用RunTime解决由NSTimer导致的内存泄漏的文章,最近和同事讨论觉得这样写有点复杂,然后发现有NSProxy这么好用的根类,根类,根类,没错NSProxy与NSObject一样是根类,都遵守<NSObject>协议。
实际上本篇用了消息转发的机制来避免NSTimer内存泄漏的问题,无论是NSProxy与NSObject的派生类在Objective-C运行时找不到消息都会执行消息转发。所以这个解决方案用NSProxy与NSObject的子类都能实现,不过NSProxy从类名来看是代理类专门负责代理对象转发消息的。相比NSObject类来说NSProxy更轻量级,通过NSProxy可以帮助Objective-C间接的实现多重继承的功能。
NSProxy
NSProxy是一个抽象类,必须继承实例化其子类才能使用。NSproxy具体使用参考官方示例,在上面示例中通过消息转发实现了同时对NSProxy发送NSMutableString和NSMutableArray类型的消息间接的实现了多重继承。
关于消息转发
当程序运行时调用一个没有实现的方法,会采用三个消息转发步骤如果这三个步骤都不能成功那么此时程序会抛出一个异常。
1.添加方法到类对象,对于实例方法调用respondsToSelector:,对于类方法调用resolveClassMethod:。
+(BOOL)resolveClassMethod:(SEL)sel;
-(BOOL)respondsToSelector:(SEL)aSelector;
2.查找forwardingTargetForSelector:方法,该方法返回一个新对象,如果返回nil那么将跳转到下一步骤。
-(id)forwardingTargetForSelector:(SEL)aSelector;
3.通过methodSignatureForSelector:方法获取一个NSMethodSignature类型的对象,调用forwardInvocation:方法。改方法传入一个封装了NSMethodSignature的NSInvocation对象。然后该对象通过invakeWithTarget:方法将消息转发给其它对象。
-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;
- (void)forwardInvocation:(NSInvocation *)invocation;
使用NSProxy解决NSTimer内存泄漏
.h文件
#import <UIKit/UIKit.h>
@interface LSYViewController : UIViewController
@end
@interface LSYProxy : NSProxy
@property (nonatomic,weak) id obj;
@end
.m文件
#import "LSYViewController.h"
@interface LSYViewController ()
@property (nonatomic,strong) LSYProxy *proxy;
@property (nonatomic,strong) NSTimer *timer;
@property (nonatomic) NSInteger count;
@end
@implementation LSYViewController
-(void)viewDidLoad
{
[super viewDidLoad];
self.proxy = [LSYProxy alloc];
self.proxy.obj = self;
_timer = [NSTimer timerWithTimeInterval:1 target:self.proxy selector:@selector(timerEvent) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
}
-(void)timerEvent
{
NSLog(@"count---%d",(int)++_count);
}
-(void)dealloc
{
NSLog(@"---dealloc----");
[_timer invalidate];
}
@end
#pragma mark - LSYProxy Implementation
@implementation LSYProxy
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
NSMethodSignature *sig;
sig = [self.obj methodSignatureForSelector:aSelector];
return sig;
}
- (void)forwardInvocation:(NSInvocation *)invocation {
[invocation invokeWithTarget:self.obj];
}
@end
原理和我之前写的利用RunTime解决由NSTimer导致的内存泄漏是一样的,只不过实现不同,之前是利用关联对象的方法来断开NSTimer与视图之间的引用关系,这个是利用消息转发来断开NSTimer对象与视图之间的引用关系。
利用NSProxy解决NSTimer内存泄漏问题的更多相关文章
- 第四十三篇、利用NSProxy解决NSTimer内存泄漏问题
问题描述: 用NSTimer来实现每隔一定时间执行制定的任务,例如最常见的广告轮播图.如果我们在 timerWithTimeInterval:1 target:self 中指定target为当前控制器 ...
- Android性能优化之利用Rxlifecycle解决RxJava内存泄漏
前言: 其实RxJava引起的内存泄漏是我无意中发现了,本来是想了解Retrofit与RxJava相结合中是如何通过适配器模式解决的,结果却发现了RxJava是会引起内存泄漏的,所有想着查找一下资料学 ...
- NSTimer内存泄漏
用NSTimer调用 timer = [NSTimer scheduledTimerWithTimeInterval:timerInterval target:self selector:@selec ...
- AutoDispose代替RxLifecycle优雅的解决RxJava内存泄漏问题
使用过Rxjava的小伙伴都知道,在使用RxJava时如果处理不当,很可能会产生内存泄漏的问题. 我们使用rxjava最大的原因是响应式编程使我们的异步操作代码变得很优雅,在Android中,也使线程 ...
- NSTimer内存泄漏导致控制器不调用dealloc
创建定时器会在一定的间隔后执行某些操作,一般大家会这样创建定时器,这样创建的定时,self对定时器有个引用,定时器对self也有个引用,造成了循环引用,最终造成了内存泄漏,如果定时器在做下载的操作就会 ...
- 使用Xcode和Instruments调试解决iOS内存泄漏
尽管iOS 5.0加入版本号之后ARC机制,由于相互引用关系是复杂的.内存泄漏可能仍然存在.于是,懂原理是非常重要的. 这里讲述在没有ARC的情况下,怎样使用Instruments来查找程序中的内存泄 ...
- 使用pidof/kill组合命令,变相解决mediaserver内存泄漏【转】
本文转载自:https://blog.csdn.net/lj402159806/article/details/78950384 在5.1系统下mediaserver有内存泄漏的问题,原因在于使用ca ...
- 一步步调试解决iOS内存泄漏
虽然iOS 5.0版本之后加入了ARC机制,由于相互引用关系比较复杂时,内存泄露还是可能存在.所以了解原理很重要. 这里讲述在没有ARC的情况下,如何使用Instruments来查找程序中的内存泄 ...
- 调试解决iOS内存泄漏
这里讲述在没有ARC的情况下,如何使用Instruments来查找程序中的内存泄露,以及NSZombieEnabled设置的使用. 本文假设你已经比较熟悉Obj-C的内存管理机制. 实验的开发环境:X ...
随机推荐
- POJ 2029 Get Many Persimmon Trees 【 二维树状数组 】
题意:给出一个h*w的矩形,再给出n个坐标,在这n个坐标种树,再给出一个s*t大小的矩形,问在这个s*t的矩形里面最多能够得到多少棵树 二维的树状数组,求最多能够得到的树的时候,因为h,w都不超过50 ...
- UVa 12545 Bits Equalizer【贪心】
题意:给出两个等长的字符串,0可以变成1,?可以变成0和1,可以任意交换s中任意两个字符的位置,问从s变成t至少需要多少次操作 先可以画个草图 发现需要考虑的就是 1---0 0---1 ?---0 ...
- .NET Framework 3.5 无法安装以下功能 安装错误:0x800F0906(客户端加域后出现)
问题:安装错误:0x800F0906 系统安装并加域后,在安装用友软件时提示没有.net 3.5 系统为win10 但是,点击确定后,却出现了这样的错误.如下: 点击下载并安装此功能,出现了这样 ...
- oralce模糊查询之含有通配符
oracle中通配符有 '_'和'%'当like '_ww%'时,会把'_'和'%'当作通配符使用导致查不出含有'_'和'%'的数据.这时用到转译字符 like '\_ww\%' escape '\ ...
- 【BZOJ 1192】[HNOI2006]鬼谷子的钱袋
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 设k为最大的正整数满足 \(2^0+2^1+...+2^k<=m\) 如果\(m>2^0+2^1+...+2^k\) 那 ...
- DBCA创建数据库ORA-01034 ORACLE not available
SYMPTOMS 在利用dbca创建数据库时,当设置完毕全部參数.開始装时 跑到2% 就报错 ORA-01034 ORACLE not available, 例如以下图 watermark/2/tex ...
- hdu5105Math Problem(分类讨论)
题目链接: huangjing 题目: 思路: 给出的是一个方程,首先讨论最高项系数. 1:a==0&& b==0 那么函数就是线性的.直接比較端点就可以. 2 a==0& ...
- nyoj--218--Dinner(语法)
Dinner 时间限制:100 ms | 内存限制:65535 KB 难度:1 描述 Little A is one member of ACM team. He had just won the ...
- 数论之证明数n等于其因数的欧拉函数值之和
定理: 任何正整数n等于其因数的欧拉函数值之和,即∑d|nφ(d)=n 证明: 设一个集合{1/n,2/n,3/n,...,(n-1)/n,n/n} 对于上述的分式集合,若我们都将其化简至最简形式,设 ...
- 解决Linux下yum安装无法解析URL的问题
问题: [root@yaya ~]# yum -y install gcc-* Loaded plugins: fastestmirror, presto Could not retrieve mir ...