1.定时器相关问题

问题

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

你可能感兴趣的:(1.定时器相关问题)