ios

NSTimer、CADisplayLink、GCD定时器

2018-07-25  本文已影响30人  紫荆秋雪_文

一、NSTimer

测试NSTimer的工程介绍

点击NSTimerBtn跳转到最左边控制器,NSTimer开始工作;点击Back时定时器停止工作

NSTimer工程介绍.png

实例一

/**
   已经加入到runloop中的定时器

   @param ti 间隔时间
   @param aTarget 执行任务的target
   @param aSelector 执行任务方法
   @param userInfo 参数
   @param yesOrNo 是否重复
   @return 定时器
 */
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;
#import "ViewController.h"

@interface ViewController ()

/** NSTimer */
@property (nonatomic, strong) NSTimer *timer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerFun:) userInfo:@"参数" repeats:YES];
}

- (void)timerFun:(NSTimer *)timer {
    
    NSLog(@"%s --%@--%@", __func__, [NSThread currentThread], timer.userInfo);
    
}

- (void)dealloc {
    NSLog(@"%s", __func__);
    [self.timer invalidate];
    self.timer = nil;
}

@end
2018-07-25 11:00:53.487606+0800 NSTimer[2046:70846] -[ViewController timerFun:] --<NSThread: 0x60000006bb00>{number = 1, name = main}--参数
2018-07-25 11:00:54.488425+0800 NSTimer[2046:70846] -[ViewController timerFun:] --<NSThread: 0x60000006bb00>{number = 1, name = main}--参数
2018-07-25 11:00:55.487701+0800 NSTimer[2046:70846] -[ViewController timerFun:] --<NSThread: 0x60000006bb00>{number = 1, name = main}--参数
2018-07-25 11:00:56.487452+0800 NSTimer[2046:70846] -[ViewController timerFun:] --<NSThread: 0x60000006bb00>{number = 1, name = main}--参数

1、使用__weak解决循环引用(解决不了NSTimer的循环引用)

#import "ViewController.h"

@interface ViewController ()

/** NSTimer */
@property (nonatomic, strong) NSTimer *timer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    __weak typeof(self)weakSelf = self;
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:weakSelf selector:@selector(timerFun:) userInfo:@"参数" repeats:YES];
}

- (void)timerFun:(NSTimer *)timer {
    
    NSLog(@"%s --%@--%@", __func__, [NSThread currentThread], timer.userInfo);
    
}

- (void)dealloc {
    NSLog(@"%s", __func__);
    [self.timer invalidate];
    self.timer = nil;
}
@end
2018-07-25 11:21:00.788221+0800 NSTimer[2325:86420] -[ViewController timerFun:] --<NSThread: 0x60000007edc0>{number = 1, name = main}--参数
2018-07-25 11:21:01.788937+0800 NSTimer[2325:86420] -[ViewController timerFun:] --<NSThread: 0x60000007edc0>{number = 1, name = main}--参数
2018-07-25 11:21:02.788234+0800 NSTimer[2325:86420] -[ViewController timerFun:] --<NSThread: 0x60000007edc0>{number = 1, name = main}--参数
2018-07-25 11:21:03.787947+0800 NSTimer[2325:86420] -[ViewController timerFun:] --<NSThread: 0x60000007edc0>{number = 1, name = main}--参数
2018-07-25 11:21:04.788652+0800 NSTimer[2325:86420] -[ViewController timerFun:] --<NSThread: 0x60000007edc0>{number = 1, name = main}--参数
2018-07-25 11:21:05.787843+0800 NSTimer[2325:86420] -[ViewController timerFun:] --<NSThread: 0x60000007edc0>{number = 1, name = main}--参数

2、使用消息转发来解决循环引用

可以创建一个中间对象来充当这个target,由于上面的分析,NSTimer是一定会强引用这个target,也就是中间件,所以只能使用中间件弱引用来指向self来解决NSTimer的target循环引用

#import <Foundation/Foundation.h>

@interface RevanProxy : NSObject

/**
 构造中间件
 */
+(instancetype)revan_proxy:(id)target;

@end

#import "RevanProxy.h"

@interface RevanProxy ()

/** target */
@property (nonatomic, weak) id target;

@end

@implementation RevanProxy

/**
 构造中间件
 */
+(instancetype)revan_proxy:(id)target {
    RevanProxy *proxy = [[RevanProxy alloc] init];
    proxy.target = target;
    return proxy;
}


/**
 消息转发

 @param aSelector 消息
 @return 执行消息的对象
 */
- (id)forwardingTargetForSelector:(SEL)aSelector {
    return self.target;
}

@end
#import "ViewController.h"
#import "RevanProxy.h"

@interface ViewController ()

/** NSTimer */
@property (nonatomic, strong) NSTimer *timer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:[RevanProxy revan_proxy:self] selector:@selector(timerFun:) userInfo:@"参数" repeats:YES];
}

- (void)timerFun:(NSTimer *)timer {
    
    NSLog(@"%s --%@--%@", __func__, [NSThread currentThread], timer.userInfo);
    
}

- (void)dealloc {
    NSLog(@"%s", __func__);
    [self.timer invalidate];
    self.timer = nil;
}

@end
2018-07-25 11:39:02.230742+0800 NSTimer[2581:99832] -[ViewController timerFun:] --<NSThread: 0x6000002612c0>{number = 1, name = main}--参数
2018-07-25 11:39:03.231457+0800 NSTimer[2581:99832] -[ViewController timerFun:] --<NSThread: 0x6000002612c0>{number = 1, name = main}--参数
2018-07-25 11:39:04.230871+0800 NSTimer[2581:99832] -[ViewController timerFun:] --<NSThread: 0x6000002612c0>{number = 1, name = main}--参数
2018-07-25 11:39:04.558871+0800 NSTimer[2581:99832] -[ViewController dealloc]

实践二

/**
   定时器

   @param interval 时间间隔
   @param repeats 是否重复
   @param block 任务block
*/
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block;
#import "ViewController.h"

@interface ViewController ()

/** NSTimer */
@property (nonatomic, strong) NSTimer *timer;

@end

@implementation ViewController

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

- (void)timerFun {
    
    NSLog(@"%s --%@", __func__, [NSThread currentThread]);
    
}

- (void)dealloc {
    NSLog(@"%s", __func__);
    [self.timer invalidate];
    self.timer = nil;
}

@end
2018-07-25 14:41:52.997761+0800 NSTimer[12605:235494] -[ViewController timerFun] --<NSThread: 0x604000079c40>{number = 1, name = main}
2018-07-25 14:41:53.998005+0800 NSTimer[12605:235494] -[ViewController timerFun] --<NSThread: 0x604000079c40>{number = 1, name = main}
2018-07-25 14:41:54.997632+0800 NSTimer[12605:235494] -[ViewController timerFun] --<NSThread: 0x604000079c40>{number = 1, name = main}
2018-07-25 14:41:55.997932+0800 NSTimer[12605:235494] -[ViewController timerFun] --<NSThread: 0x604000079c40>{number = 1, name = main}
2018-07-25 14:41:56.997607+0800 NSTimer[12605:235494] -[ViewController timerFun] --<NSThread: 0x604000079c40>{number = 1, name = main}
2018-07-25 14:41:57.998040+0800 NSTimer[12605:235494] -[ViewController timerFun] --<NSThread: 0x604000079c40>{number = 1, name = main}
2018-07-25 14:41:58.997908+0800 NSTimer[12605:235494] -[ViewController timerFun] --<NSThread: 0x604000079c40>{number = 1, name = main}
2018-07-25 14:41:59.997616+0800 NSTimer[12605:235494] -[ViewController timerFun] --<NSThread: 0x604000079c40>{number = 1, name = main}
2018-07-25 14:42:00.998211+0800 NSTimer[12605:235494] -[ViewController timerFun] --<NSThread: 0x604000079c40>{number = 1, name = main}

1、使用__weak来解决NSTimer的block循环引用

#import "ViewController.h"

@interface ViewController ()

/** NSTimer */
@property (nonatomic, strong) NSTimer *timer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    __weak typeof(self) weakSelf = self;
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
        [weakSelf timerFun];
    }];
    
}

- (void)timerFun {
    
    NSLog(@"%s --%@", __func__, [NSThread currentThread]);
    
}

- (void)dealloc {
    NSLog(@"%s", __func__);
    [self.timer invalidate];
    self.timer = nil;
}

@end
2018-07-25 14:52:21.773549+0800 NSTimer[13007:244135] -[ViewController timerFun] --<NSThread: 0x60000007d2c0>{number = 1, name = main}
2018-07-25 14:52:22.773903+0800 NSTimer[13007:244135] -[ViewController timerFun] --<NSThread: 0x60000007d2c0>{number = 1, name = main}
2018-07-25 14:52:23.773437+0800 NSTimer[13007:244135] -[ViewController timerFun] --<NSThread: 0x60000007d2c0>{number = 1, name = main}
2018-07-25 14:52:24.359867+0800 NSTimer[13007:244135] -[ViewController dealloc]

实践三

/**
   创建定时器

   @param ti 时间间隔
   @param aTarget 执行任务target
   @param aSelector 需要执行的任务
   @param userInfo 参数
   @param yesOrNo 是否重复
*/
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;

#import "ViewController.h"

@interface ViewController ()

/** NSTimer */
@property (nonatomic, strong) NSTimer *timer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timerFun) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
    //子线程runloop需要手动开启
//    [NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture];
}

- (void)timerFun {
    
    NSLog(@"%s --%@", __func__, [NSThread currentThread]);
    
}

- (void)dealloc {
    NSLog(@"%s", __func__);
    [self.timer invalidate];
    self.timer = nil;
}

@end
2018-07-25 17:40:31.560835+0800 NSTimer[17231:373102] -[ViewController timerFun] --<NSThread: 0x604000260c80>{number = 1, name = main}
2018-07-25 17:40:32.560742+0800 NSTimer[17231:373102] -[ViewController timerFun] --<NSThread: 0x604000260c80>{number = 1, name = main}
2018-07-25 17:40:33.560538+0800 NSTimer[17231:373102] -[ViewController timerFun] --<NSThread: 0x604000260c80>{number = 1, name = main}
2018-07-25 17:40:34.560385+0800 NSTimer[17231:373102] -[ViewController timerFun] --<NSThread: 0x604000260c80>{number = 1, name = main}
2018-07-25 17:40:35.560674+0800 NSTimer[17231:373102] -[ViewController timerFun] --<NSThread: 0x604000260c80>{number = 1, name = main}

解决循环引用

因为是NSTimer的target引用所以我在选择中间件来解决循环应用

#import <Foundation/Foundation.h>

@interface RevanProxy : NSObject

/**
 构造中间件
 */
+(instancetype)revan_proxy:(id)target;

@end

#import "RevanProxy.h"

@interface RevanProxy ()

/** target */
@property (nonatomic, weak) id target;

@end

@implementation RevanProxy

/**
 构造中间件
 */
+(instancetype)revan_proxy:(id)target {
    RevanProxy *proxy = [[RevanProxy alloc] init];
    proxy.target = target;
    return proxy;
}


/**
 消息转发

 @param aSelector 消息
 @return 执行消息的对象
 */
- (id)forwardingTargetForSelector:(SEL)aSelector {
    return self.target;
}

@end
#import "ViewController.h"
#import "RevanProxy.h"

@interface ViewController ()

/** NSTimer */
@property (nonatomic, strong) NSTimer *timer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.timer = [NSTimer timerWithTimeInterval:1.0 target:[RevanProxy revan_proxy:self] selector:@selector(timerFun) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
    //子线程runloop需要手动开启
//    [NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture];
}

- (void)timerFun {
    
    NSLog(@"%s --%@", __func__, [NSThread currentThread]);
    
}

- (void)dealloc {
    NSLog(@"%s", __func__);
    [self.timer invalidate];
    self.timer = nil;
}

@end
2018-07-25 17:43:15.562021+0800 NSTimer[17310:375348] -[ViewController timerFun] --<NSThread: 0x60000006e500>{number = 1, name = main}
2018-07-25 17:43:16.562049+0800 NSTimer[17310:375348] -[ViewController timerFun] --<NSThread: 0x60000006e500>{number = 1, name = main}
2018-07-25 17:43:17.089576+0800 NSTimer[17310:375348] -[ViewController dealloc]

实践四

/**
   定时器

   @param interval 间隔时间
   @param repeats 重复
   @param block 任务block
*/
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block;
#import "ViewController.h"

@interface ViewController ()

/** NSTimer */
@property (nonatomic, strong) NSTimer *timer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.timer = [NSTimer timerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
        [self timerFun];
    }];
    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
    //子线程runloop需要手动开启
//    [NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture];
}

- (void)timerFun {
    
    NSLog(@"%s --%@", __func__, [NSThread currentThread]);
    
}

- (void)dealloc {
    NSLog(@"%s", __func__);
    [self.timer invalidate];
    self.timer = nil;
}

@end
2018-07-25 17:52:52.583498+0800 NSTimer[17610:384088] -[ViewController timerFun] --<NSThread: 0x604000066b00>{number = 1, name = main}
2018-07-25 17:52:53.582260+0800 NSTimer[17610:384088] -[ViewController timerFun] --<NSThread: 0x604000066b00>{number = 1, name = main}
2018-07-25 17:52:54.582224+0800 NSTimer[17610:384088] -[ViewController timerFun] --<NSThread: 0x604000066b00>{number = 1, name = main}
2018-07-25 17:52:55.582232+0800 NSTimer[17610:384088] -[ViewController timerFun] --<NSThread: 0x604000066b00>{number = 1, name = main}
2018-07-25 17:52:56.582231+0800 NSTimer[17610:384088] -[ViewController timerFun] --<NSThread: 0x604000066b00>{number = 1, name = main}
2018-07-25 17:52:57.583263+0800 NSTimer[17610:384088] -[ViewController timerFun] --<NSThread: 0x604000066b00>{number = 1, name = main}

解决NSTimer的block循环

#import "ViewController.h"

@interface ViewController ()

/** NSTimer */
@property (nonatomic, strong) NSTimer *timer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    __weak typeof(self) weakSelf = self;
    self.timer = [NSTimer timerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
        [weakSelf timerFun];
    }];
    
    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
    //子线程runloop需要手动开启
//    [NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture];
}

- (void)timerFun {
    
    NSLog(@"%s --%@", __func__, [NSThread currentThread]);
    
}

- (void)dealloc {
    NSLog(@"%s", __func__);
    [self.timer invalidate];
    self.timer = nil;
}

@end
2018-07-25 18:00:47.782248+0800 NSTimer[17767:390307] -[ViewController timerFun] --<NSThread: 0x60400007f6c0>{number = 1, name = main}
2018-07-25 18:00:48.782537+0800 NSTimer[17767:390307] -[ViewController timerFun] --<NSThread: 0x60400007f6c0>{number = 1, name = main}
2018-07-25 18:00:49.782184+0800 NSTimer[17767:390307] -[ViewController timerFun] --<NSThread: 0x60400007f6c0>{number = 1, name = main}
2018-07-25 18:00:50.782352+0800 NSTimer[17767:390307] -[ViewController timerFun] --<NSThread: 0x60400007f6c0>{number = 1, name = main}
2018-07-25 18:00:51.056397+0800 NSTimer[17767:390307] -[ViewController dealloc]

小结

二、CADisplayLink

#import "ViewController.h"

@interface ViewController ()

/** CADisplayLink */
@property (nonatomic, strong) CADisplayLink *displayLink;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(timerFun)];
    
    [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}

- (void)timerFun {
    
    NSLog(@"%s --%@", __func__, [NSThread currentThread]);
    
}

- (void)dealloc {
    NSLog(@"%s", __func__);
    [self.displayLink invalidate];
    self.displayLink = nil;
}

@end
2018-07-25 18:29:21.257630+0800 NSTimer[18426:414584] -[ViewController timerFun] --<NSThread: 0x60000006fbc0>{number = 1, name = main}
2018-07-25 18:29:21.260929+0800 NSTimer[18426:414584] -[ViewController timerFun] --<NSThread: 0x60000006fbc0>{number = 1, name = main}
2018-07-25 18:29:21.277595+0800 NSTimer[18426:414584] -[ViewController timerFun] --<NSThread: 0x60000006fbc0>{number = 1, name = main}
2018-07-25 18:29:21.294965+0800 NSTimer[18426:414584] -[ViewController timerFun] --<NSThread: 0x60000006fbc0>{number = 1, name = main}
2018-07-25 18:29:21.310950+0800 NSTimer[18426:414584] -[ViewController timerFun] --<NSThread: 0x60000006fbc0>{number = 1, name = main}
2018-07-25 18:29:21.328056+0800 NSTimer[18426:414584] -[ViewController timerFun] --<NSThread: 0x60000006fbc0>{number = 1, name = main}
2018-07-25 18:29:21.344301+0800 NSTimer[18426:414584] -[ViewController timerFun] --<NSThread: 0x60000006fbc0>{number = 1, name = main}

使用中间件RevanProxy解决CADisplayLink循环引用

#import <Foundation/Foundation.h>

@interface RevanProxy : NSObject

/**
 构造中间件
 */
+(instancetype)revan_proxy:(id)target;

@end


#import "RevanProxy.h"

@interface RevanProxy ()

/** target */
@property (nonatomic, weak) id target;

@end

@implementation RevanProxy

/**
 构造中间件
 */
+(instancetype)revan_proxy:(id)target {
    RevanProxy *proxy = [[RevanProxy alloc] init];
    proxy.target = target;
    return proxy;
}


/**
 消息转发

 @param aSelector 消息
 @return 执行消息的对象
 */
- (id)forwardingTargetForSelector:(SEL)aSelector {
    return self.target;
}

@end

#import "ViewController.h"
#import "RevanProxy.h"

@interface ViewController ()

/** CADisplayLink */
@property (nonatomic, strong) CADisplayLink *displayLink;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.displayLink = [CADisplayLink displayLinkWithTarget:[RevanProxy revan_proxy:self] selector:@selector(timerFun)];
    
    [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}

- (void)timerFun {
    
    NSLog(@"%s --%@", __func__, [NSThread currentThread]);
    
}

- (void)dealloc {
    NSLog(@"%s", __func__);
    [self.displayLink invalidate];
    self.displayLink = nil;
}

@end
2018-07-25 18:37:04.564087+0800 NSTimer[18612:422374] -[ViewController timerFun] --<NSThread: 0x604000064880>{number = 1, name = main}
2018-07-25 18:37:04.580233+0800 NSTimer[18612:422374] -[ViewController timerFun] --<NSThread: 0x604000064880>{number = 1, name = main}
2018-07-25 18:37:04.597601+0800 NSTimer[18612:422374] -[ViewController timerFun] --<NSThread: 0x604000064880>{number = 1, name = main}
2018-07-25 18:37:04.613840+0800 NSTimer[18612:422374] -[ViewController timerFun] --<NSThread: 0x604000064880>{number = 1, name = main}
2018-07-25 18:37:04.630309+0800 NSTimer[18612:422374] -[ViewController timerFun] --<NSThread: 0x604000064880>{number = 1, name = main}
2018-07-25 18:37:04.647850+0800 NSTimer[18612:422374] -[ViewController timerFun] --<NSThread: 0x604000064880>{number = 1, name = main}
2018-07-25 18:37:04.664557+0800 NSTimer[18612:422374] -[ViewController timerFun] --<NSThread: 0x604000064880>{number = 1, name = main}
2018-07-25 18:37:04.680940+0800 NSTimer[18612:422374] -[ViewController timerFun] --<NSThread: 0x604000064880>{number = 1, name = main}
2018-07-25 18:37:04.688731+0800 NSTimer[18612:422374] -[ViewController dealloc]

三、GCD定时器

#import "ViewController.h"

@interface ViewController ()
@property (nonatomic, strong) dispatch_source_t gcdTimer;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //1.队列
    dispatch_queue_t queue = dispatch_get_main_queue();
    //2.创建定时器
    self.gcdTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    //3.设置时间
    // start 秒后开始执行
    uint64_t start = 2.0;
    // 每隔interval执行
    uint64_t interval = 1.0;
    
    dispatch_source_set_timer(self.gcdTimer, dispatch_time(DISPATCH_TIME_NOW, start * NSEC_PER_SEC), interval * NSEC_PER_SEC, 0);
    
    //4.设置回调
    dispatch_source_set_event_handler(self.gcdTimer, ^{
        [self timerFire];
    });
    
    //5.启动定时器
    dispatch_resume(self.gcdTimer);
}

- (void)timerFire {
    NSLog(@"2222 - %@", [NSThread currentThread]);
}

- (void)dealloc {
    self.gcdTimer = nil;
    NSLog(@"%s", __func__);
}

@end
2018-07-25 23:26:07.602187+0800 09-GCD定时器[37249:2261911] 2222 - <NSThread: 0x600000061b80>{number = 1, name = main}
2018-07-25 23:26:08.602584+0800 09-GCD定时器[37249:2261911] 2222 - <NSThread: 0x600000061b80>{number = 1, name = main}
2018-07-25 23:26:09.602216+0800 09-GCD定时器[37249:2261911] 2222 - <NSThread: 0x600000061b80>{number = 1, name = main}
2018-07-25 23:26:10.602594+0800 09-GCD定时器[37249:2261911] 2222 - <NSThread: 0x600000061b80>{number = 1, name = main}
2018-07-25 23:26:11.602276+0800 09-GCD定时器[37249:2261911] 2222 - <NSThread: 0x600000061b80>{number = 1, name = main}
2018-07-25 23:26:12.601514+0800 09-GCD定时器[37249:2261911] 2222 - <NSThread: 0x600000061b80>{number = 1, name = main}

解决GCD中block循环引用

#import "ViewController.h"

@interface ViewController ()
@property (nonatomic, strong) dispatch_source_t gcdTimer;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //1.队列
    dispatch_queue_t queue = dispatch_get_main_queue();
    //2.创建定时器
    self.gcdTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    //3.设置时间
    // start 秒后开始执行
    uint64_t start = 2.0;
    // 每隔interval执行
    uint64_t interval = 1.0;
    
    dispatch_source_set_timer(self.gcdTimer, dispatch_time(DISPATCH_TIME_NOW, start * NSEC_PER_SEC), interval * NSEC_PER_SEC, 0);
    
    //4.设置回调
    __weak typeof(self)weakSelf = self;
    dispatch_source_set_event_handler(self.gcdTimer, ^{
        [weakSelf timerFire];
    });
    //5.启动定时器
    dispatch_resume(self.gcdTimer);
}

- (void)timerFire {
    NSLog(@"%s - %@", __func__, [NSThread currentThread]);
}

- (void)dealloc {
    self.gcdTimer = nil;
    NSLog(@"%s", __func__);
}

@end

2018-07-25 23:30:56.361956+0800 09-GCD定时器[37317:2266010] -[ViewController timerFire] - <NSThread: 0x60400006be80>{number = 1, name = main}
2018-07-25 23:30:57.361294+0800 09-GCD定时器[37317:2266010] -[ViewController timerFire] - <NSThread: 0x60400006be80>{number = 1, name = main}
2018-07-25 23:30:58.362232+0800 09-GCD定时器[37317:2266010] -[ViewController timerFire] - <NSThread: 0x60400006be80>{number = 1, name = main}
2018-07-25 23:30:59.361211+0800 09-GCD定时器[37317:2266010] -[ViewController timerFire] - <NSThread: 0x60400006be80>{number = 1, name = main}
2018-07-25 23:30:59.495951+0800 09-GCD定时器[37317:2266010] -[ViewController dealloc]

五、小结

上一篇下一篇

猜你喜欢

热点阅读