美文网首页
iOS 定时器

iOS 定时器

作者: GTMYang | 来源:发表于2018-05-31 17:19 被阅读0次

iOS常用定时器有3种

  • NSTimer
  • GCD定时器 dispatch_source_t
  • CADisplayLink 与屏幕刷新率同步的通知

精准度

  • NSTimer因为runloop的运行机制,会存在延时
  • CADisplayLink在页面掉帧的情况下会不太准,不掉帧的情况下比较精准
  • GCD定时器比NSTimer更精准

各种定时器的使用

// 创建

// NSTimer创建方式1(此种方式需要手动添加到runloop才开始执行)
NSTimer *_timer1 = [NSTimer timerWithTimeInterval:3 target:self selector:@selector(timer1) userInfo:nil repeats:YES];
/**********
 手动添加到runloop,为了保证timer一定执行需要添加到NSRunLoopCommonModes下,
该模式中的source和timer会拷贝到所有其他的模式下。
如果加在NSDefaultRunLoopMode,在UIScrollView拖动的时候timer不会执行,
因为在UIScrollView拖动拖动的时候住线程自动被系统切换到UITrackingRunLoopMode.
****/ 
[[NSRunLoop mainRunLoop] addTimer:_timer1 forMode:NSRunLoopCommonModes];

// NSTimer创建方式2 (此种方式不用手动添加runloop,立即开始执行)
_timer2 = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(timer2) userInfo:nil repeats:YES];

// CADisplayLink
CADisplayLink *_displayLink = [CADisplayLink displayLinkWithTarget:wapper selector:@selector(displayLink)];
        _displayLink.frameInterval = 60; // 1s执行一次,不掉帧的刷新频率60次每秒
        [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

// gcd timer
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
        dispatch_source_set_timer(_timer, DISPATCH_TIME_NOW, 3.0 * NSEC_PER_SEC, 0);
       // __weak typeof(self) weakSelf = self;
        dispatch_source_set_event_handler(_timer, ^{
           // DO balabalabala...
        });
        // 开启定时器
        dispatch_resume(_timer);

// 销毁
// NSTimer
  [_timer1 invalidate];
    [_timer2 invalidate];
    // CADIsplayLink
    [_displayLink invalidate];
// GCD
    dispatch_source_cancel(_timer);

关于内存泄漏

v

正常情况下Timer的生命周期必然比其Target小,所以这里只要想办法将Timer对Target的强引用转换成弱引用,然后我们就能在Target的delloc方法中执行Timer的销毁方法。

** 利用runtime我设计了一个处理方式 **

// WeakWrapper.h
#import <Foundation/Foundation.h>
@interface WeakWrapper : NSObject
- (instancetype)initWith:(id)willWeak;
@end

// WeakWrapper.m
#import "WeakWrapper.h"
#import <objc/runtime.h>

@interface WeakWrapper()
@property (nonatomic, weak) id weakObj;
@end

@implementation WeakWrapper
- (instancetype)initWith:(id)willWeak {
    if ([super init]) {
        self.weakObj = willWeak;
    }
    return self;
}
- (instancetype)init {
    [self doesNotRecognizeSelector:_cmd];
    return nil;
}
// 消息转发
- (id)forwardingTargetForSelector:(SEL)aSelector {
     return _weakObj;
}
@end

// 使用
WeakWrapper *wapper = [[WeakWrapper alloc] initWith:self];
_timer1 = [NSTimer timerWithTimeInterval:3 target: wapper selector:@selector(doTimer) userInfo:nil repeats:YES];

代码封装

针对iOS的Timer我封装了一个类库 GTM_Timer
简介:

  • 支持用block创建各类Timer(NSTimer, GCD timer, CADisplayLink)
  • 解决了Timer的保留环造成的内存泄漏的问题

相关文章

  • 无标题文章

    iOS NSTimer使用详解-开启、关闭、移除 定时器定时器详解ios定时器关闭定时器NSTimer 1、要使用...

  • iOS进阶-谈谈定时器

    目录 iOS提供定时器API 定时器开发中的坑 一、 iOS提供定时器API 二、定时器开发中的坑 2.1、必须办...

  • 定时器

    定时器 兼容ios

  • iOS中的定时器

    点击这里>> cocoaChina: iOS中的定时器 iOS中定时器有三种,分别是NSTimer、CADispl...

  • GCD定时器使用

    iOS中的常用定时器分为这几类: NSTimer CADisplayLink GCD定时器 选择GCD定时器原因:...

  • iOS:NSTimer的几种创建方式

    在iOS开发中,经常会用到定时器,iOS中常用的定时器有三种:NSTimer,GCD,CADisplayLink。...

  • iOS Timer

    iOS开发中定时器经常会用到,iOS中常用的定时器有三种,分别是NSTime,CADisplayLink和GCD。...

  • 每日笔记

    1、通过safari打开网页 2、iOS的几种定时器及区别 iOS的几种定时器及区别 3、long long类型 ...

  • iOS三大定时器

    iOS开发中定时器经常会用到,iOS中常用的定时器有三种,分别是NSTime,CADisplayLink和GCD。...

  • 定时器的使用介绍

    iOS中的定时器大致分为这几类: NSTimer CADisplayLink GCD定时器 (一)NSTimer ...

网友评论

      本文标题:iOS 定时器

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