RunLoop

作者: spades_K | 来源:发表于2018-01-30 16:12 被阅读12次

    含义:运行循环 偏底层

    原理: iOS在 UIApplicationMain()中开启,

    目的:
    1.保证程序不退出。

    1. 监听事件 触摸、时钟、网络事件。(所有事件跟硬件有关 响应式)

    2. 如果没有事件发生,让程序进入休眠状态。

    //
    //  ViewController.m
    //  RunLoop
    //
    //  Created by john on 2018/1/30.
    //  Copyright © 2018年 john. All rights reserved.
    //
    
    #import "ViewController.h"
    
    @interface ViewController ()
    {
        dispatch_source_t timer;
    }
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        
    }
    
    - (void)otherMethod
    {
        NSLog(@"%@",[NSThread currentThread]);
    
    }
    
    
    
    - (void)demo1
    {
        /*
         // 封装下面两个  默认模式
         [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timeActiom) userInfo:nil repeats:YES];
         */
        
        NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timeActiom) userInfo:nil repeats:YES];
        
        // 默认模式 当视图进行拖动时,事件不被调用
        [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
        
        //  UI模式只在触摸事件才触发
        [[NSRunLoop mainRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
        
        //  占位模式 等于前两个之和的效果
        [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
        
        
        
        // timer事件会在UI拖拽过程中是不会执行的
        
        
        // runLoop模式
        /*
         1 默认模式   Source  Observe Timer  当视图进行拖动时,事件不被调用
         2 UI模式    Source  Observe Timer   优先级最高  只能被触摸事件所触发
         3 占位模式  NSRunLoopCommonModes
         */
    }
    
    - (void)demo2
    {
        // 子线程
        NSThread *thread = [[NSThread alloc] initWithBlock:^{
            
            NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timeActiom) userInfo:nil repeats:YES];
            
            [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
            
            // 让runLoop跑起来  死循环  不会再执行下面代码
            // currentRunLoop 会调用CFRunloop() 第一次获取runLoop的时候创建RunLoop 懒加载
            [[NSRunLoop currentRunLoop] run]; // 跑起来停不了
            
            NSLog(@"来了"); //  runLoop没跑起来  对于事件 这个可以打印
            
            
            // 线程的生命要想保存  只能让它有执行不完的任务。
            //        while (true) {
            //        }
            
            
        }];
        
        [thread start];
    
    }
    
    
    - (void)demo3
    {
        
        NSThread *thred = [[NSThread alloc] initWithBlock:^{
            
            NSLog(@"%@",[NSThread currentThread]);
        }];
        
        
        [thred start];
        
        // 线程通讯
        [self performSelector:@selector(otherMethod) onThread:thred withObject:nil waitUntilDone:NO];  // 这个 otherMethod方法不会走的 因为线程已经挂掉了  需要线程保活   事件中的通讯是runloop处理的
    
    }
    
    - (void)demo4
    {
        // GCD实现
        //1 创建 timer
        timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0));
        // 设置 timer 1 秒一次
        dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC, 0);
        
        // 设置回调
        dispatch_source_set_event_handler(timer, ^{
            NSLog(@"%@",[NSThread currentThread]);
        });
        
        // 启动
        dispatch_resume(timer);
        
        
        /*
         Runloop中的source
         底层为 CFRunLoopSourceRef
         
         按照函数调用栈分类:
         Source0 : 不是Source1的就是Source0
         Source1: 内核和其他线程通讯事件。
         
         */
        
    
    }
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        // 杀掉主线程  程序整体无反应  但是子线程中runLoop还在跑
        /*
         UI是在主线程上面的
         app启动的第一条线程
         why 苹果这样设计  ?
         A: 安全加效率   UIKIT框架是线程不安全的框架  多线程会出现资源抢夺的情况 安全的话可以加线程锁 但是会出现效率低下的情况  所以苹果这么限制
         
         
         */
        [NSThread exit];
        
    }
    
    
    - (void)timeActiom
    {
        NSLog(@"come l "); // 子线程中runloop不会走这个方法  因为此时线程已经被释放  如果用成员变量对这个线程持有,线程还是会被释放,持有的只是这个对象而已。
        // 耗时操作
    //    [NSThread sleepForTimeInterval:1];
        NSLog(@"%@",[NSThread currentThread]);
    }
    
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    
    @end
    
    参考AF线程保活的方法
    + (void)networkRequestThreadEntryPoint:(id)__unused object {
        @autoreleasepool {
            [[NSThread currentThread] setName:@"AFNetworking"];
    
            NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
            [runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
            [runLoop run];
        }
    }
    

    相关文章

      网友评论

          本文标题:RunLoop

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