Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS 中的定时器 #100

Open
ShannonChenCHN opened this issue Dec 20, 2017 · 2 comments
Open

iOS 中的定时器 #100

ShannonChenCHN opened this issue Dec 20, 2017 · 2 comments

Comments

@ShannonChenCHN
Copy link
Owner

ShannonChenCHN commented Dec 20, 2017

  • 实现定时器的几种方式
    • NSTimer
    • NSObject 的 -performSelector:withObject:afterDelay:
    • GCD
      • dispatch_after
      • dispatch_source_t
    • CADisplayLink
    • 使用 mach 内核级的函数可以使用 mach_absolute_time() 获取到 CPU 的 tickcount 的计数值,可以通过 mach_timebase_info 函数获取到纳秒级的精确度 。然后使用 mach_wait_until(uint64_t deadline) 函数,直到指定的时间之后,就可以执行指定任务了。
  • 使用 NSTimer 时,如何避免造成循环引用
  • NSTimer 的实现,NSTimer 跟 Runloop 的关系
@ShannonChenCHN
Copy link
Owner Author

ShannonChenCHN commented Dec 20, 2017

@ShannonChenCHN
Copy link
Owner Author

ShannonChenCHN commented Dec 20, 2017

使用 NSTimer 时,如何避免造成循环引用

一、为什么会造成循环引用

二、如何避免

方法一:定义一个中间 target 给 NSTimer 持有,这个 target 再对 self 进行弱引用,从而打破循环引用

           NSTimer ——> proxyTarget ----->self
                ↑________________________|
            注:虚线代表弱引用

方法二:通过 block 对要执行的任务进行封装,然后再将这个 block 传进 userInfo 参数中,最后,在外面的 block 中使用时,使用 weakSelf

      @implementation NSTimer (Helper)
      + (NSTimer *)eoc_scheduledTimerWithTimeInterval:(NSTimeInterval)inTimeInterval block:(void (^)())inBlock repeats:(BOOL)inRepeats
      {
      void (^block)() = [inBlock copy];
      NSTimer * timer = [self scheduledTimerWithTimeInterval:inTimeInterval target:self selector:@selector(eoc_executeTimerBlock:) userInfo:block repeats:inRepeats];
      return timer;
      }
      
      + (NSTimer *)eoc_timerWithTimeInterval:(NSTimeInterval)inTimeInterval block:(void (^)())inBlock repeats:(BOOL)inRepeats
      {
      void (^block)() = [inBlock copy];
      NSTimer * timer = [self timerWithTimeInterval:inTimeInterval target:self selector:@selector(eoc_executeTimerBlock:) userInfo:block repeats:inRepeats];
      return timer;
      }
      
      + (void)eoc_executeTimerBlock:(NSTimer *)inTimer;
      {
      if([inTimer userInfo])
      {
      void (^block)() = (void (^)())[inTimer userInfo];
      block();
      }
      }
      @end

方法三(不推荐):如果是在 UIView 的子类中使用,可以通过重写 willMoveToSuperview 方法,在 view 即将从 superview 上移除时销毁 NSTimer 对象

参考

This was referenced Dec 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant