宽容他人,放过自己。

NSTimer的实现

Posted on By anchoriteFili

#pragma mark CADisplayLink 是一个定时器,特点 刷新频率高,  setNeedsDisplay方法起重新绘制的作用
    CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)];
    [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    
#pragma mark 定时器执行方法
    [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(setNeedsDisplay) userInfo:nil repeats:YES];

CADisplayLink示例

#import "ViewController.h"

#define IMAGE_COUNT 10

@interface ViewController () {
    CALayer *_layer;
    int _index;
    NSMutableArray *_images;
}

@end

/**
 ReadMe
 虽然在核心动画没有直接提供逐帧动画类型,但是却提供了用于完成逐帧动画的相关对象CADisplayLink。
 CADiplayLink是一个计时器,但是同NSTimer不同的是,CADisplayLink的刷新周期同屏幕完全一致。
 例如在iOS中屏幕刷新周期是60次/秒,CADisplayLink刷新周期同屏幕刷新一致也是60次/秒,这样以来
 使用它完全的逐帧动画(又称“时钟动画”)完全感觉不到动画的停滞情况
 */

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    //设置背景
    self.view.layer.contents = (id)[UIImage imageNamed:@"底板"].CGImage;
    
    //创建图像显示图层
    _layer = [[CALayer alloc] init];
    _layer.bounds = CGRectMake(0, 0, 87, 32);
    _layer.position = CGPointMake(100, 340);
    [self.view.layer addSublayer:_layer];
    
    //由于与的图片在循环中会不断创建,而10张鱼的图片相对都很小
    //与其在循环中不断创建UIImage不如直接将10张图片缓存起来
    
    _images = [NSMutableArray array];
    for (int i = 0; i < 3; ++ i) {
        NSString *imageName = [NSString stringWithFormat:@"%d",i+1];
        
        UIImage *image = [UIImage imageNamed:imageName];
        [_images addObject:image];
    }
    
    //定义时钟对象
    CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(step)];
    //添加时钟对象到主运行循环
    [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}

#pragma mark 每次屏幕刷新都会执行一次次方法(每秒接近60次)
- (void)step {
    //定义一个变量记录执行次数
    static int s = 0;
    if (_index >= 3) {
        _index = 1;
    }
    //每秒执行6次
    if (++s%3 == 0) {
        UIImage *image = _images[_index];
        _layer.contents = (id)image.CGImage; //更新图片
        _index = (_index+1)%IMAGE_COUNT;
    }
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

NSTimer示例

#pragma mark 开始按钮,创建时间控制器
- (void)begin:(UIButton *)sender {
    if (!self.timer) {
//        创建NSTimer_self.timer
        self.timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(action:) userInfo:nil repeats:YES];
//        将创建的self.timer加入到循环中
        [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
//        让循环跑起来
        [[NSRunLoop currentRunLoop] run];
        
    }
}

#pragma mark 点击结束按钮,让时间控制器停止
- (void)end:(UIButton *)sender {
    if (self.timer) {
        NSLog(@"时间流逝");
//        当时间控制器存在时,停止timer,invalidate [ɪn'vælɪdeɪt]使无效
        [self.timer invalidate];
        self.timer = nil;
    }
}

#pragma mark 创建时间控制器控制事件
- (void)action:(NSTimer *)timer {
    NSLog(@"nowTime = %@",[NSDate date]);
}