NSTimer 的相关问题

NSTimer 循环引用问题

使用此方法创建,会形成循环引用,即使在dealloc中调用
[self.timer invalidate]以及self.timer = nil;也是解决不了循环引用的问题。

产生循环引用原因:当前VC 持有timer,但是timer有对传入的target有强引用,以此形成循环引用。

self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerTest) userInfo:nil repeats:YES];

解决方法:
1.通过中间件来进行解除循环引用,使用代理对象来进行强引用timer, vc对其代理对象弱引用,以此来解决。
创建一个代理对象LProxy,

LProxy.h
@interface LProxy : NSObject

+(instancetype)proxyWithTarget:(id)target;
@property (nonatomic, weak) id target;

@end
LProxy.m
#import <objc/runtime.h>
@implementation LProxy
+(instancetype)proxyWithTarget:(id)target{
    LProxy *p = [[LProxy alloc]init];
    p.target = target;
    return p;
}
//此处是为了在使用时target为当前的LProxy,但是找不到LProxy的timerTest方法出现carch,通过消息转发来实现消息的接受者为传入的target来,以此解决因找不到target的方法出现的carch
- (id)forwardingTargetForSelector:(SEL)aSelector{
    return self.target;
}
@end
在使用的时候,通过代理对象的target来进行一步弱引用解决循环
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:[LProxy proxyWithTarget:self] selector:@selector(timerTest) userInfo:nil repeats:YES];

或者LProxy直接继承NSProxy来实现消息的方法签名以及消息的转发,

LProxy.h
@interface LProxy : NSProxy
+ (instancetype)proxyWithTarget:(id)target;
@property (nonatomic, weak) id target;
@end

LProxy.m
@implementation LProxy
+ (instancetype)proxyWithTarget:(id)target{
    LProxy *proxy = [LProxy alloc];
    proxy.target = target;
    return proxy;
}

//方法签名
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel{
    return [self.target methodSignatureForSelector:sel];
}
//将方法签名的sel转发为当前的target来进行消息转发
- (void)forwardInvocation:(NSInvocation *)invocation{
    [invocation invokeWithTarget:self.target];
}

@end

2.或者直接把NSTimer的创建也放在代理对象实现,通过代理方法把时间间隔以及执行方法暴露给外界使用, 此时也能解决NSTimer循环引用问题。

3.使用下来方法类进行创建,不对其self进行强引用

self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
        
    }];

NSTimer 使用准时吗? 解决方法?

NSTimer使用不准时,因为NStimer底层是基于NSRunloop的,如果Runloop的任务过于繁重,可能会导致NSTimer不准时,可以使用GCD的定时器,因为GCD定时器不依赖于runloop,它依赖系统内核。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. 什么是NSTimer   官方的解释“A timer provides a way to perform a...
    Timir阅读 4,266评论 0 3
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 13,794评论 1 32
  • 引言 定时器:A timer waits until a certain time interval has el...
    时间已静止阅读 7,801评论 6 34
  • 定时器的用法 系统提供了8个创建方法,6个类创建方法,2个实例初始化方法。有三个方法直接将timer添加到...
    gpylove阅读 5,762评论 1 3
  • Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允...
    JWking阅读 1,196评论 0 1