美文网首页
运行循环 RunLoop

运行循环 RunLoop

作者: HFY_Code | 来源:发表于2016-07-24 12:28 被阅读0次
Paste_Image.png Paste_Image.png RunLoop应用.jpg

观察RunLoop的活动阶段


- (void)observer
{
    
    /**
     *  用block创建runloop观察者
     *
     *  CFAllocatorRef allocator 分配器  类型:为创建对象分配内存
     *  CFOptionFlags activities runloop活动阶段 类型:在Core Foundation中CFOptionFlags是一个针对于特定不透明类型和函数的标志位
     *  Boolean repeats 是否循环,
     *  CFIndex order 指定观察者的运行优先级,一般传0
     *
     */
    CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopBeforeTimers, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
        NSLog(@"----监听到RunLoop状态发生改变---%zd", activity);
    });

    /**
     *  添加观察者查看runloop的活动
     *  
     *  CFRunLoopRef rl  当前要观察的runloop
     *  CFRunLoopObserverRef observer  观察者
     *  CFStringRef mode  runloop运行的模式
     */
    
    CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode);
    
    // 释放Observer
    CFRelease(observer);
    
    /*
     CF的内存管理(Core Foundation)
     1.凡是带有Create、Copy、Retain等字眼的函数,创建出来的对象,都需要在最后做一次release
     * 比如CFRunLoopObserverCreate
     2.release函数:CFRelease(对象);
     */
}

定时器

#pragma mark计划调度
- (void)timer2
{
    // 调用了scheduledTimer返回的定时器,已经自动被添加到当前runLoop中,而且是NSDefaultRunLoopMode,如果是在子线程,还需开启runloop
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
    
    // 修改模式
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}

#pragma mark普通定时器
- (void)timer
{
    NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
    // 定时器只运行在NSDefaultRunLoopMode下,一旦RunLoop进入其他模式,这个定时器就不会工作
    //    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    
    // 定时器只运行在UITrackingRunLoopMode下,一旦RunLoop进入其他模式,这个定时器就不会工作
    //    [[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
    
    // 定时器会跑在标记为common modes的模式下
    // 标记为common modes的模式:UITrackingRunLoopMode和NSDefaultRunLoopMode
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}

图片加载

- (void)useImageView
{
    // 只在NSDefaultRunLoopMode模式下显示图片
    [self.imageView performSelector:@selector(setImage:) withObject:[UIImage imageNamed:@"placeholder"] afterDelay:3.0 inModes:@[NSDefaultRunLoopMode]];
}

线程常驻


#pragma mark 创建永驻线程
- (void)addThread
{
    //创建一条线程去处理任务,当任务结束后,线程进入消亡状态,无法再次开启
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
    [thread start];
}
- (void)run
{
    //只需在线程任务中的runloop中添加一个端口,就可以使线程永驻
    [[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] run];
    
    //永远不调用,触发runloop退出
    NSLog(@"---------");
}
#pragma mark 利用永驻线程处理其他任务
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self performSelector:@selector(test) onThread:self.thread withObject:nil waitUntilDone:NO];
}

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

CD定时器


#import "ViewController.h"

@interface ViewController ()
/** 定时器(这里不用带*,因为dispatch_source_t就是个类,内部已经包含了*) */
@property (nonatomic, strong) dispatch_source_t timer;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
}

int count = 0;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    // 获得队列
    dispatch_queue_t queue = dispatch_get_main_queue();
    
    // 创建一个定时器(dispatch_source_t本质还是个OC对象)
    self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    
    // 设置定时器的各种属性(几时开始任务,每隔多长时间执行一次)
    // GCD的时间参数,一般是纳秒(1秒 == 10的9次方纳秒)
    // 何时开始执行第一个任务
    // dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC) 比当前时间晚1秒
    dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC));
    uint64_t interval = (uint64_t)(1.0 * NSEC_PER_SEC);
    dispatch_source_set_timer(self.timer, start, interval, 0);
    
    // 设置回调
    dispatch_source_set_event_handler(self.timer, ^{
        NSLog(@"------------%@", [NSThread currentThread]);
        count++;
        
        if (count == 4) {
            // 取消定时器
            dispatch_cancel(self.timer);
            self.timer = nil;
        }
    });
    
    // 启动定时器
    dispatch_resume(self.timer);
}

相关文章

  • RunLoop详解

    RunLoop详解 RunLoop运行循环(死循环) RunLoop模式 NSDefaultRunLoopMode...

  • RunLoop概念与响应者链

    一.RunLoop简介 什么是RunLoop? RunLoop就是运行循环,在程序运行的过程中循环做一些事情,如果...

  • 教你如何轻松搞定 Runloop

    认识 Runloop Runloop 就是运行循环,如果没有 Runloop,程序一运行就会退出,有 Runloo...

  • iOS-Runloop1-Runloop

    一. RunLoop相关 什么是Runloop?顾名思义,Runloop就是运行循环,就是在程序运行过程中循环做一...

  • 【iOS】Runloop

    Runloop概念 运行循环(死循环) Runloop作用 保持程序的持续运行 处理app中的各种事件 节省CPU...

  • RunLoop

    RunLoop简介 RunLoop,就是一个运行循环,通过一个内部的运行循环(Event Loop)对事件或者消息...

  • NSRunLoop

    RunLoop运行逻辑 RunLoop面试题: 1、什么是RunLoop? 答:从字面意思上:运行循环、跑圈。 其...

  • 初探Runloop

    1.runloop是什么? runloop 是一个运行循环(死循环); return UIApplicationM...

  • 简单谈谈RunLoop

    1、RunLoop定义 从字面上看,run是运行,执行的意思,loop是循环的意思,其实RunLoop就是运行循环...

  • RunLoop基础

    RunLoop简介 RunLoop运行循环,在程序运行过程中循环做一些事情.如:定时器(Timer)、Perfor...

网友评论

      本文标题:运行循环 RunLoop

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