iOS基於GCD開發的定時器

系統提供的NSTimer類,很多的時候內存的釋放是一個大問題,尤其是repeat方式的,通過調試發現它是基本上不釋放的。我個人就考慮用GCD來實現一套定時器的功能。詳細見下面的code:

//
//  DispatchTimer.h
//  WYJDemoSets
//
//  Created by wuyj on 16/2/18.
//  Copyright © 2016年 wuyj. All rights reserved.
//

#import <Foundation/Foundation.h>


@protocol DispatchTimerDelegate <NSObject>
- (void)dispatchTimerTask;
@end

typedef void (^DispatchTimerBlock)(void);

/*
 採用GCD實現timer,這個實現不會出現timer不釋放的問題;
 */
@interface DispatchTimer :NSObject

+ (DispatchTimer *)sharedDispatchTimer;

// 採用代理的方式,建議採用這種方式
- (void)createDispatchTimerInterval:(NSUInteger)interval delegate:(id <DispatchTimerDelegate>)delegate repeats:(BOOL)yesOrNo;

/* !!!!!! 採用block的方式,一定要注意block retain self的問題

 類似這樣使用:
 __weak CycleScrollView *wself = self;
 [[DispatchTimer sharedDispatchTimer] createDispatchTimerInterval:_interval block:^{
 CycleScrollView *sself = wself;

 [sself autoJumpPage];
 } repeats:YES];
 */

- (void)createDispatchTimerInterval:(NSUInteger)interval block:(DispatchTimerBlock)timerBlock repeats:(BOOL)yesOrNo;

// 停止循環執行的timer
- (void)invalidate;

@end

//
//  DispatchTimer.m
//  WYJDemoSets
//
//  Created by wuyj on 16/2/18.
//  Copyright © 2016年 wuyj. All rights reserved.
//

#import "DispatchTimer.h"

@interface DispatchTimer ()
@property (nonatomic,strong) dispatch_source_t timer;
@property (nonatomic,weak) id<DispatchTimerDelegate> delegate;

@end

@implementation DispatchTimer

+ (DispatchTimer *)sharedDispatchTimer {

    staticDispatchTimer *obj = nil;
    staticdispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        obj = [[selfalloc] init];
    });
    return obj;
}

- (void)dealloc {
    [selfinvalidate];
}

- (void)createDispatchTimerInterval:(NSUInteger)interval delegate:(id <DispatchTimerDelegate>)delegate repeats:(BOOL)yesOrNo {

    self.delegate = delegate;

    if (yesOrNo) {
        // 獲得隊列
        dispatch_queue_t queue =dispatch_get_main_queue();
        self.timer =dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,0, 0, queue);
        dispatch_time_t start =dispatch_time(DISPATCH_TIME_NOW, (int64_t)(interval *NSEC_PER_SEC));
        uint64_t dur = (uint64_t)(interval *NSEC_PER_SEC);
        dispatch_source_set_timer(self.timer, start, dur,0);

        // 設置回調
        __weakDispatchTimer *wTimer = self;
        dispatch_source_set_event_handler(self.timer,^{

            //執行事件
            DispatchTimer *sTimer = wTimer;
            if (sTimer.delegate && [sTimer.delegaterespondsToSelector:@selector(dispatchTimerTask)]) {
                [sTimer.delegatedispatchTimerTask];
            }

        });

        // 啓動定時器
        dispatch_resume(self.timer);
    } else {
        dispatch_time_t popTime =dispatch_time(DISPATCH_TIME_NOW, interval *NSEC_PER_SEC);

        // 設置回調
        __weakDispatchTimer *wTimer = self;
        dispatch_after(popTime,dispatch_get_main_queue(), ^(void){

            //執行事件
            DispatchTimer *sTimer = wTimer;
            if (sTimer.delegate && [sTimer.delegaterespondsToSelector:@selector(dispatchTimerTask)]) {
                [sTimer.delegatedispatchTimerTask];
            }

        });
    }
}


- (void)createDispatchTimerInterval:(NSUInteger)interval block:(DispatchTimerBlock)timerBlock repeats:(BOOL)yesOrNo {

    if (yesOrNo) {
        // 獲得隊列
        dispatch_queue_t queue =dispatch_get_main_queue();
        self.timer =dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,0, 0, queue);
        dispatch_time_t start =dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 *NSEC_PER_SEC));
        uint64_t dur = (uint64_t)(interval *NSEC_PER_SEC);
        dispatch_source_set_timer(self.timer, start, dur,0);

        // 設置回調
        dispatch_source_set_event_handler(self.timer, timerBlock);

        // 啓動定時器
        dispatch_resume(self.timer);
    } else {
        dispatch_time_t popTime =dispatch_time(DISPATCH_TIME_NOW, interval *NSEC_PER_SEC);
        dispatch_after(popTime,dispatch_get_main_queue(), timerBlock);
    }
}

- (void)invalidate {
    if (self.timer) {
        dispatch_cancel(self.timer);
        self.timer =nil;
    }
}

@end
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章