基于dispatch_after封装YXTimer

本人根据dispatch_after封装了一个定时器,支持block以及代理的方式来激活定时器,适用于对精度要求低,耗时短的地方,高端大气上档次,低调奢华有内涵:)

源码:

YXTimer.h 与 YXTimer.m

//
//  YXTimer.h
//  YXTimer
//
//  Created by YouXianMing on 14-10-2.
//  Copyright (c) 2014年 YouXianMing. All rights reserved.
//

#import <Foundation/Foundation.h>
@class YXTimer;

@protocol YXTimerDelegete <NSObject>
- (void)YXTimerEvent:(YXTimer *)timer;
@end

@interface YXTimer : NSObject

// 代理相关方法
@property (nonatomic) NSTimeInterval              milliSecond; // 毫秒
@property (nonatomic, assign) id<YXTimerDelegete> delegate;

// block相关方法
+ (instancetype)timerWithMilliSecondInterval:(NSTimeInterval)milliSecond
                                       Block:(void (^)(YXTimer *timer))block;

// 激活定时器 + 停止定时器
- (void)start;
- (void)stop; // 注意:要想让timer能被移除,一定要激活stop方法才行

@end
//
//  YXTimer.m
//  YXTimer
//
//  Created by YouXianMing on 14-10-2.
//  Copyright (c) 2014年 YouXianMing. All rights reserved.
//

#ifdef DEBUG
#define YXTimer_DLog(fmt, ...) NSLog((@"YXTimer.m:%s:%d" fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#define YXTimer_DLog(...)
#endif

#import "YXTimer.h"

@interface YXTimer ()

@property (nonatomic) BOOL isRunning;
@property (nonatomic, copy) void (^block)(YXTimer *timer);

@end

@implementation YXTimer

- (instancetype)init
{
    self = [super init];
    if (self) {
        _isRunning = NO;
    }
    return self;
}

- (instancetype)initWithBlock:(void (^)(YXTimer *timer))block {
    self = [super init];

    if (self) {
        _isRunning = NO;
        _block     = block;
    }

    return self;
}

- (void)start {
    _isRunning = YES;
    [self runTimer];
}

- (void)stop {
    _isRunning = NO;
}

+ (instancetype)timerWithMilliSecondInterval:(NSTimeInterval)milliSecond
                                       Block:(void (^)(YXTimer *timer))block {
    YXTimer *timer = [[YXTimer alloc] initWithBlock:block];
    timer.milliSecond = milliSecond;

    return timer;
}

- (void)runTimer {

    if (self.isRunning) {

        NSTimeInterval  milliSecond = 1000.f;
        if (_milliSecond > 0) {
            milliSecond = _milliSecond;
        }

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(milliSecond * NSEC_PER_MSEC)), dispatch_get_main_queue(), ^{
            if (self.block) {
                self.block(self);
            }

            if (_delegate) {
                [_delegate YXTimerEvent:self];
            }

            [self runTimer];
        });
    }
}

- (void)dealloc {
    [self stop];
    YXTimer_DLog(@"资源释放了");
}

@end

使用源码:

//
//  ViewController.m
//  YXTimer
//
//  Created by YouXianMing on 14-10-2.
//  Copyright (c) 2014年 YouXianMing. All rights reserved.
//

#import "ViewController.h"
#import "YXTimer.h"

@interface ViewController ()<YXTimerDelegete>

@property (nonatomic, strong) YXTimer   *timer;
@property (nonatomic, strong) UILabel   *label;
@property (nonatomic, strong) NSArray   *dataArray;
@property (nonatomic)         NSInteger  count;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    _dataArray = @[@"Y.X. Loading .",
                   @"Y.X. Loading ..",
                   @"Y.X. Loading ...",
                   @"Y.X. Loading ....",
                   @"Y.X. Loading .....",
                   @"Y.X. Loading ......",
                   @"Y.X. Loading ......."];

    _timer             = [YXTimer new];
    _timer.milliSecond = 100;
    _timer.delegate    = self;
    [_timer start];

    _label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, 30)];
    _label.textAlignment = NSTextAlignmentLeft;
    _label.font = [UIFont fontWithName:@"HelveticaNeue-Thin" size:20.f];
    _label.textColor = [UIColor redColor];
    _label.center = self.view.center;
    [self.view addSubview:_label];

}

- (void)YXTimerEvent:(YXTimer *)timer
{
    _label.text = _dataArray[_count++ % _dataArray.count];
}

@end

需要注意的地方:

时间: 2024-09-29 06:32:02

基于dispatch_after封装YXTimer的相关文章

OSS.Core基于Dapper封装(表达式解析+Emit)仓储层的构思及实现

最近趁着不忙,在构思一个搭建一个开源的完整项目,至于原因以及整个项目框架后边文章我再说明.既然要起一个完整的项目,那么数据仓储访问就必不可少,这篇文章我主要介绍这个新项目(OSS.Core)中我对仓储层的简单思考和实现过程(当前项目还处在搭建阶段),主要集中在以下几个方面: 1. 数据仓储层的需求 2. ORM框架选择 3. OSS.Core仓储层设计实现 4. 调用示例 下边的实现部分中可能需要你对.NET的 泛型,委托,扩展,表达式等有一个基础了解.正是因为这些语言特性,方便我们对操作共性的

VC基于API封装串口类(只有一个头文件)

因工作的需要,采用了基于VC开发项目,因需要用到串口,这里面没用到windows的MSCOMM空间和CSerialPot的类,而是专门利用windows api函数的同步机制来封装此类,类的接口模式有点模仿QT的Win_QextSerialPort.本库可以直接用在MFC上,当然也可以移植到QT上面. #pragma once #include<Windows.h> #include <math.h> #define MAX_RECV_BUFFER 1024 #define MAX

基于 ECharts 封装甘特图并实现自动滚屏

项目中需要用到甘特图组件,之前的图表一直基于 EChart 开发,但 EChart 本身没有甘特图组件,需要自行封装 经过一番鏖战,终于完成了... 我在工程中参考 v-chart 封装了一套图表组件,所以这里只介绍甘特图组件的实现,图表的初始化.数据更新.自适应等不在这里介绍 一.约定数据格式 EChart 本身没有甘特图,但可以通过 EChart 提供的“自定义”方法 type: 'custom' 开发 const option = { series: [{ type: 'custom',

基于wke封装的duilib的webkit浏览器控件,可以c++与js互交,源码及demo下载地址

转载请说明原出处,谢谢~~ 前些日子用wke内核封装了duilib的webkit浏览器控件,好多群里朋友私聊我希望可以我公布源码,今天把这个控件的源码和使用demo公布.其实这个控件封装起来没什么难度,我只是按照原来作者的demo,把相应的消息封装成duilib对应的. 在此首先要感谢wke内核的作者BlzFans以及soui2界面库的作者flyhigh,BlzFans精简了webkit内核后封装为wke并公布了源码,flyhigh对wke进行处理让他更容易移植到dui工程中.wke内核10M大

基于JavaScript封装的Ajax工具类

前段是件由于工作需要无奈编写了一个给予JavaScript封装的工具类,技术有限,误喷,感谢大家的支持. 1.以下是JavaScript 的 Ajax 工具类. function createXMLHttpRequest(){ var req; if(window.XMLHttpRequest){ //兼容非IE 并且兼容 IE7以上的浏览器 req = new XMLHttpRequest(); }else if(window.ActiveXObject){ //在 Internet Expl

基于Vue封装分页组件

使用Vue做双向绑定的时候,可能经常会用到分页功能 接下来我们来封装一个分页组件 先定义样式文件 pagination.css ul, li { margin: 0px; padding: 0px;} .page-bar { -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-sel

基于layer封装的异步加载分部视图弹出层

背景:之前一直用的artdialog,但是样式不是很好看,后来偶然看到layer,觉得不错,但是对于.net mvc来说,不能像artdialog一样弹出分部视图是很难受的.所以下面的方法就解决了. <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta na

基于业务封装API进行Redis服务性能测试记录

背景 开发方面给予redis开源客户端做了二次封装,且做了reids集群部署:ld要求对redis服务性能做一次摸底测试: 测试需求 单实例的读写压力极限 单机的读写压力极限(可能瓶颈在网卡) proxy单实例的压力极限 proxy单机的压力极限 主备的切换的可靠性测试 ------------ 本次未做 平滑迁移的有效性  ------------ 本次未做 迁移对访问性能的影响(可选) ------------ 本次未做 从上述开发提出的需求看出,本次是以性能验证为主要目的的一次测试:运行场

基于ElementUI封装可复用的表格组件

<template> <section class="ces-table-page"> <!-- 表格操作按钮 --> <section class="ces-handle" v-if='isHandle'> <el-button v-for='item in tableHandles' :key='item.label' :size="size || item.size" :type=&qu