[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fsb1ZARzubAjyCR4Yj4RKsADmEsZg743MDqaNphX7WEw":3},{"code":4,"message":5,"data":6},200,"成功",{"id":7,"createdAt":8,"title":9,"content":10,"summary":11,"image":12,"uid":13,"user":14,"categoryId":21,"category":22,"subCategoryId":24,"subCategory":25,"comments":27,"status":17,"reason":12,"notice":12,"visitCount":28,"commentCount":29,"keywords":30},36,"2024-01-29T15:18:53.727Z","Runloop底层原理分析","# Runloop\n\n*   Runloop一个运行循环，是一个对象.\n*   包含一个do while循环\n*   提供一个入口函数，程序可以进入一个do while循环\n*   消息机制处理模式\n\nC: 运行->计算->完成->退出\n\n## 作用：\n\n*   保持程序的持续进行\n*   处理app中的各种事件（触摸、定时器、performSelecor）\n*   节省cpu资源、提供程序的性能：该做事就做事，该休息就休息\n\n## 处理\n\n*   block应用: `__CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__`\n\n*   调用timer用: `__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__`\n\n*   响应source0: `__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__`\n\n*   响应source1: `__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__`\n\n*   GCD主队列: `__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__`\n\n*   observer源: `__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__`\n\n*   [x] 线程和runloop通过key-value的形式一一对应.\n\n*   [x] 子线程的runloop默认不开启\n\n*   [x] 基于线程创建runloop\n\n*   [x] 通过变量 -- 线程 -- runloop -- timer\n\n*   [x] timer依赖于runloop\n\n\u003C!---->\n\n    NSThread *thread = [[NSThread alloc] initWithBlock:^{\n        NSLog(@\"%@\", [NSThread currentThread]);\n        [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^{\n            NSLog(@\"子线程timer\");\n            if (self.isStopping) {\n                [NSThread exit];\n            }\n        }];\n        [[NSRunloop currentRunLoop] run];\n    }];\n    thread.name = @\"xxxxx\";\n    [thread start];\n\n1.  Timer为什么不准？ \\\\\n\n*   [x] 在default和tracking mode切换.\n\n1.  一个runloop对应多个mode，一个mode对应于多个timer，source，observers.\n2.  timer是如何加入runloop？\n    runLoopRun \\\n    runLoopDoBlocks \\\n    while循环执行item并执行timer等 \\\n    timer加入的mode和我们现在runloop的mode相等\\\n    curr->\\_mode = KCFRunLoopCommonModes相等.\n\n*   timer一定要加入到相应的runloop的mode， timer加到items\n*   runloopRun -> doBlock -> while\n*   [x] item->next\n*   [x] doit\n*   [x] block调用\n\n\u003C!---->\n\n    -(void)cfTimerDemo {\n        CFRunLoopTimerContext context = {\n            0,\n            ((__bridge void*)self),\n            NULL,\n            NULL,\n            NULL\n        };\n        CFRunLoopRef rlp = CFRunLoopGetCurrent();\n        /**\n        参数一：用于分配对象的内存\n        参数二：在什么时候触发（距离现在）\n        参数三：每个多少时间出发一次\n        参数四：未来参数\n        参数五：CFRunLoopObserver的优先级 当在RunLoop同一运行阶段中有多个CFRunLoopObserver 正常情况下使用0\n        参数六：回调，比如触发事件，我就会来到这里\n        参数七：上下文记录信息\n        */\n        CFRunLoopTimerRef timerRef = CFRunLoopTimerCreate(kCFAllocatorDefault, 0, 1, 0, 0, lgRunLoopTimerCallBack, &context);\n        CFRunLoopAddTimer(rlp, timerRef, kCFRunLoopDefaultMode);\n    }\n    void lgRunLoopTimerCallBack(CFRunLoopTimerRef timer, void *info) {\n        NSLog(@\"%@---%@\", timer, info);\n    }\n\n1.  observer\n\n*   监听runloop的状态.\n*   其demo和timer类似.\n\n1.  source\n\n*   source0，回调函数指针\n\n*   [x] 一个signal 待处理\n\n*   [x] wake up唤醒runloop处理事件\n\n*   [x] 作用：处理app内部事件\n\n*   [x] 作用：app自己负责管理的事务, 触摸事件等 UIEvent、CFSocket\n\n*   source1 mach\\_port & 回调函数指针\n\n*   [x] runloop和内核管理\n\n*   [x] port\n\n*   [x] 线程之间通讯\n\n*   实用技巧：\n\n*   [x] 卡顿检测\n\n*   [x] FPS\n\n","这里是runloop原理相关的介绍，还有runloop的运行机制，及其中的一些细节解释。","",499668042977349,{"phone":15,"userId":13,"nickName":16,"vipType":17,"avatar":18,"sign":19,"createdAt":20},"13121171998","全栈老韩",1,"https://image.xinwei.ltd/images/IMG_5430.JPG","全栈工程师，擅长iOS App开发、前端（vue、react、nuxt、小程序&Taro）开发、Flutter、React Native、后端（midwayjs、golang、express、koa）开发、docker容器、seo优化等。","2024-01-01T16:14:30.305Z",2,{"id":21,"name":23},"IT技术",3,{"id":24,"name":26,"parentId":21},"iOS",[],67,0,"ios,ios开发,runloop,ios runloop"]