NSTime

作者: 飞哥漂流记 | 来源:发表于2020-05-27 13:39 被阅读0次

看看timer最常用的写法:

@interface TimerViewController ()

@property (nonatomic, strong) NSTimer *timer;

@end

@implementation TimerViewController

- (void)viewDidLoad {

    [super viewDidLoad];

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

    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];

}

- (void)timerRun {

    NSLog(@"%s", __func__);

}

- (void)dealloc {

    [self.timer invalidate];

    NSLog(@"%s", __func__);

}

@end

但是当回退到上一个控制器的时候,发现并没有走当前控制器的dealloc方法,也就是说当前控制器并没有被释放,那么当前控制器强引用的timer对象也没有被释放,这就造成了内存泄漏,如下图所示。

这里的每一个箭头代表着一个强指针,当回退上一个界面时,NavigationController指向TimerViewController的强引用被销毁,但是TimerViewController和timer之间互相强引用,内存泄漏。

解决方法1:

在这里加入了一个中间代理对象LJProxy,TimerViewController不直接持有timer,而是持有LJProxy实例,让LJProxy实例来弱引用TimerViewController,timer强引用LJProxy实例,直接看代码

@interface LJWeakProxy : NSProxy

+ (instancetype)proxyWithTarget:(id)target;

@property (weak, nonatomic) id target;

@end

@implementation LJWeakProxy

+ (instancetype)proxyWithTarget:(id)target {

    LJWeakProxy *proxy = [LJWeakProxy alloc];

    proxy.target = target;

    return proxy;

}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {

    return [self.target methodSignatureForSelector:sel];

}

- (void)forwardInvocation:(NSInvocation *)invocation {

    [invocation invokeWithTarget:self.target];

}

@end

Controller里只修改了下面一句代码:

- (void)viewDidLoad {

    [super viewDidLoad];

    // 这里的target又发生了变化

    self.timer = [NSTimer timerWithTimeInterval:1.0 target:[LJWeakProxy proxyWithTarget:self] selector:@selector(timerRun) userInfo:nil repeats:YES];

    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];

}

解决方法2:通过消息转发的方法的方式

@interface TimerViewController ()

@property (nonatomic, strong) NSTimer *timer;

@end

@implementation TimerViewController

- (void)viewDidLoad {

    [super viewDidLoad];

    __weak typeof(self) weakSelf = self;

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

        [weakSelf timerRun];

    }];

}

- (void)timerRun {

    NSLog(@"%s", __func__);

}

- (void)dealloc {

    [self.timer invalidate];

    NSLog(@"%s", __func__);

}

解决方法3:

需要定时器在 UIScrollView 滑动时也不影响的话,有两种解决方法:

给NSTimer分别添加到UITrackingRunLoopMode 和 NSDefaultRunLoopMode这两个模式中:

[[NSRunLoop mainRunLoop] addTimer:timer

forMode:NSDefaultRunLoopMode];

[[NSRunLoop mainRunLoop] addTimer:timer

forMode: UITrackingRunLoopMode];

给NSTimer添加NSRunLoop的NSRunLoopCommonModes中,平常用这中就可以了,比较简便来:

[[NSRunLoop mainRunLoop] addTimer:timer

forMode: NSRunLoopCommonModes];

1. 用定时器有遇到什么问题吗?(是否准时?循环引用)

2. NSTimer是如何释放的?

3.如何实现一个倒计时功能,类似于蘑菇街的秒杀?

首先用NSDateFormatter获取当前时间字符串 然后使用GCD

dispatch_queue_t queue = dispatch_get_globe_queue{

dispatch_source_t *timer = dispatch_source_creat(

dispatch_source_set_timer

)

dispatch_source_set_event_handle_timer^{

}

}

4..触发的timer在滑动时会暂停回调,为什么?

5. 定时器什么时候销毁,一些通知,KVO放在哪里销毁?

答案和其他问题待更新!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

相关文章

  • 0707-NSTime

    NSTime 定时器 创建NSTime

  • NSTime

    看看timer最常用的写法: @interface TimerViewController ()@property...

  • NSTime使用

    NSTimer Use 1.初始化 a)[NSTimerscheduledTimerWithTimeInterva...

  • Runloop与NSTime

    本文授权转载,作者:@方秋枋 目标:用简洁易懂的语言归纳runLoop和对我们日常开发的影响。 1. 什么是Run...

  • 通知 NSTime Delegate

    1. NSTimer循环引用怎么解决?能用__weak吗 解决办法: 由于循环引用的起因是target,则可以包装...

  • 摩拜-APP 使用的lib

    MSWeakTimer:代替 NSTime NSTimer 工作原理: 官方解释是“A timer provide...

  • iOS 定时器

    pragma mark----定时器 (void)beginTimer {self.timer = [NSTime...

  • 倒计时的实现方法

    方法一:NSTimer 1> 创建定时器属性 @property(strong,nonatomic)NSTime...

  • iOS开发(13)内存管理

    一、定时器的内存 1、CADisplayLink、NSTimer使用注意 CADisplayLink、NSTime...

  • 从定时器到RunLoop

    ios 常用的定时器有三种:NSTime,CADisplayLink和GCD。 NsTimer // 参数:Int...

网友评论

      本文标题:NSTime

      本文链接:https://www.haomeiwen.com/subject/myokahtx.html