zoukankan      html  css  js  c++  java
  • iOS RunLoop

    • 什么是RunLoop
      • 运行循环
      • 一个线程对应一个RunLoop,主线程的RunLoop默认已经启动,子线程的RunLoop得手动启动(调用run方法)
      • RunLoop只能选择一个Mode启动,如果当前Mode中没有任何Source(Sources0、Sources1)、Timer,那么就直接退出RunLoop
    • RunLoop作用

      • 保持程序的持续运行
      • 处理App中的各种事件(比如触摸事件、定时器事件、Selector事件)
      • 节省CPU资源,提高程序性能:该做事时做事,该休息时休息 ......
    • 模拟RunLoop内部实现

      • 其实它内部就是do-while循环,在这个循环内部不断地处理各种任务(比如Source、Timer、Observer)
      • void message(int num)
        {
            printf("执行第%i个任务", num);
        }
        int main(int argc, const char * argv[]) {
            do {
                printf("有事吗? 没事我睡了");
                int number;
                scanf("%i", &number);
                message(number);
            } while (1);
            return 0;
        }
    • 获得RunLoop对象

      • RunLoop对象
        • NSRunLoop
        • CFRunLoopRef
      • Foundation
        [NSRunLoop currentRunLoop]; // 获得当前线程的RunLoop对象
        [NSRunLoop mainRunLoop]; // 获得主线程的RunLoop对象
        
      • Core Foundation
        CFRunLoopGetCurrent(); // 获得当前线程的RunLoop对象
        CFRunLoopGetMain(); // 获得主线程的RunLoop对象
        
    • RunLoop结构

    • CFRunLoopRef对应RunLoop对象
      • CFRunLoopModeRef代表RunLoop的运行模式, 系统默认注册了5个Mode
        • NSDefaultRunLoopMode:App的默认Mode,通常主线程是在这个Mode下运行
        • UITrackingRunLoopMode:界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响
        • NSRunLoopCommonModes: 这是一个占位用的Mode,不是一种真正的Mode
      • CFRunLoopTimerRef是基于时间的触发器
        • CFRunLoopTimerRef基本上说的就是NSTimer,它受RunLoop的Mode影响
      • CFRunLoopSourceRef是事件源(输入源)
      • CFRunLoopObserverRef是观察者,能够监听RunLoop的状态改变
      • // 1.创建Observer
            // 第一个参数:用于分配该observer对象的内存
            // 第二个参数:用以设置该observer所要关注的的事件
            // 第三个参数:用于标识该observer是在第一次进入run loop时执行, 还是每次进入run loop处理时均执行
            // 第四个参数:用于设置该observer的优先级
            // 第五个参数: observer监听到事件时的回调block
            CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
                switch(activity)
                {
                    case kCFRunLoopEntry:
                        NSLog(@"即将进入loop");
                        break;
                    case kCFRunLoopBeforeTimers:
                        NSLog(@"即将处理timers");
                        break;
                    case kCFRunLoopBeforeSources:
                        NSLog(@"即将处理sources");
                        break;
                    case kCFRunLoopBeforeWaiting:
                        NSLog(@"即将进入休眠");
                        break;
                    case kCFRunLoopAfterWaiting:
                        NSLog(@"刚从休眠中唤醒");
                        break;
                    case kCFRunLoopExit:
                        NSLog(@"即将退出loop");
                        break;
                    default:
                        break;
                }
            });
        
            // 2.添加监听
            /*
             第一个参数: 给哪个RunLoop添加监听
             第二个参数: 需要添加的Observer对象
             第三个参数: 在哪种模式下监听
             */
            CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopDefaultMode);
        
            // 3,释放observer
            CFRelease(observer);
    • RunLoopRunLoop处理逻辑
    • RunLoopRunLoop应用
      • NSTimer
        • 只能在指定的model下运行
        • NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(test) userInfo:nil repeats:YES];
          [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
      • ImageView显示
        • 只能在指定的model下设置图片
      • PerformSelector
        • 只能在指定的model下调用
        • [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:[UIImage imageNamed:@"lnj"] waitUntilDone:YES modes:@[NSDefaultRunLoopMode]];
      • 常驻线程
        • 必须调用run才会执行死循环
        • NSRunLoop的model中必须有source/timer,死循环才不会退出
        • NSRunLoop *runloop = [NSRunLoop currentRunLoop];
          [runloop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
          [runloop run]
      • 自动释放池
        • activities = 0x1 = 1
          1: 即将进入RunLoop : 创建一个自动释放池
          activities = 0xa0 = 160 = 128 + 32
          32:即将休眠 : 释放上一次的自动释放池, 创建一个新的自动释放池
          128:即将退出RunLoop : 释放自动释放池

     

  • 相关阅读:
    self 和 super 关键字
    NSString类
    函数和对象方法的区别
    求两个数是否互质及最大公约数
    TJU Problem 1644 Reverse Text
    TJU Problem 2520 Quicksum
    TJU Problem 2101 Bullseye
    TJU Problem 2548 Celebrity jeopardy
    poj 2586 Y2K Accounting Bug
    poj 2109 Power of Cryptography
  • 原文地址:https://www.cnblogs.com/liujiaoxian/p/4881681.html
Copyright © 2011-2022 走看看