问题
1.定时器不准问题
2.定时器内存泄漏问题
答案
1.定时器不准问题
1.当我们使用NSTimer/CADisplayLink 的时候,会有不准的时候,是由于当时runloop 比较繁忙导致的.
2.NSTimer 停止计时,是由于当时的runloopModel 变为滚动模式导致的,要解决这个问题,我们需要把当前的timer添加到 runloopModel 为 comment标记的那个模式
2.NSTimer/CADisplayLink定时器内存泄漏问题
方案1 通过自定义的第三方NSObject
这个会走消息发送,动态解析,消息转发
@interface FAN_Proxy : NSObject
+ (instancetype)proxyWithTarget:(id)target;
@property (weak, nonatomic) id target;
@end
@implementation FAN_Proxy
+ (instancetype)proxyWithTarget:(id)target
{
FAN_Proxy *proxy = [[FAN_Proxy alloc] init];
proxy.target = target;
return proxy;
}
- (id)forwardingTargetForSelector:(SEL)aSelector
{
return self.target;
}
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:[FAN_Proxy proxyWithTarget:self] selector:@selector(timerTest) userInfo:nil repeats:YES];
@end
方案1 通过系统专门用来系统转发的类 NSProxy解决问题
这个是专门用来做 消息转发的,这个是最优的解决方案
@interface FAN_Proxy : NSProxy
+ (instancetype)proxyWithTarget:(id)target;
@property (weak, nonatomic) id target;
@end
@implementation FAN_Proxy
+ (instancetype)proxyWithTarget:(id)target
{
// NSProxy对象不需要调用init,因为它本来就没有init方法
MJProxy *proxy = [FAN_Proxy alloc];
proxy.target = target;
return proxy;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
{
return [self.target methodSignatureForSelector:sel];
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
[invocation invokeWithTarget:self.target];
}
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:[FAN_Proxy proxyWithTarget:self] selector:@selector(timerTest) userInfo:nil repeats:YES];
@end
网友评论