mirror of
https://github.com/NohamR/knowledge-kit.git
synced 2026-05-25 04:17:17 +00:00
feature: Weex APM
This commit is contained in:
@@ -35,7 +35,7 @@
|
||||
|
||||
先附上一张总结的非常棒的RunLoop图
|
||||
|
||||
<img src="./../assets/2019-05-09-RunLoop-review.png" style="zoom:30%" />
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2019-05-09-RunLoop-review.png" style="zoom:30%" />
|
||||
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ struct __CFRunLoopMode {
|
||||
|
||||
Demo:
|
||||
|
||||
<img src="./../assets/NSRunloopRoundWithCFRunloop.png" style="zoom:30%" />
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/NSRunloopRoundWithCFRunloop.png" style="zoom:30%" />
|
||||
|
||||
|
||||
|
||||
@@ -178,11 +178,11 @@ Source0:
|
||||
|
||||
Demo1:给屏幕点击事件加断点,查看堆栈可以看到是 Source0 触发的。
|
||||
|
||||
<img src="./../assets/TouchActionByRunLoopSource0.png" style="zoom:25%" />
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/TouchActionByRunLoopSource0.png" style="zoom:25%" />
|
||||
|
||||
Demo2: `- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait` 该 API 的底层就是:向目标线程的 RunLoop 添加一个 Source0 事件,标记后唤醒线程执行对应的事件。
|
||||
|
||||
<img src="./../assets/PerformThreadTaskByRunLoopSource0.png" style="zoom:25%" />
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/PerformThreadTaskByRunLoopSource0.png" style="zoom:25%" />
|
||||
|
||||
Source1:
|
||||
|
||||
@@ -221,7 +221,7 @@ CFRunLoopSourceRef 事件源(输入源)
|
||||
|
||||
### 一对多的关系
|
||||
|
||||
<img src="./../assets/ThreadRunLoopModeStructure.png" style="zoom:70%" />
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/ThreadRunLoopModeStructure.png" style="zoom:70%" />
|
||||
|
||||
|
||||
|
||||
@@ -434,7 +434,7 @@ CFRelease(obersver);
|
||||
*/
|
||||
```
|
||||
|
||||

|
||||

|
||||
|
||||
上个实验是在主线程对 RunLoop 进行的监听,但是由于是主线程是由系统创建的,所以系统也创建了对应的主 RunLoop,所以我们看不到 RunLoop 创建的状态,为了模拟完整的状态,我们开启子线程,在子线程中模拟
|
||||
|
||||
@@ -510,7 +510,7 @@ CFRelease(obersver);
|
||||
|
||||
### 运行原概要
|
||||
|
||||

|
||||

|
||||
|
||||
- 图上左上角的 Input source 是早期 RunLoop 的分法,现在分法为:Source0 和 Source1。
|
||||
- Source0:非基于 port 的,用户主动触发的事件。
|
||||
@@ -527,7 +527,7 @@ CFRelease(obersver);
|
||||
|
||||
但是如何直到系统是运行 RunLoop 的哪个函数?给 viewDidLoad 设置断点,在 lldb 模式输入 `bt` 查看堆栈
|
||||
|
||||

|
||||

|
||||
|
||||
查看 CF 中 `CFRunLoop.c`源码。方法比较复杂,做了精简摘要
|
||||
|
||||
@@ -1137,7 +1137,7 @@ RunLoop 内部几个核心的动作:`__CFRunLoopDoObservers`、`__CFRunLoopSer
|
||||
|
||||
上面结合源码看了 Runloop 是怎么运行的。下面通过图片看看 RunLoop 各个状态运行切换的完整流程。
|
||||
|
||||
<img src="./../assets/RunLoop-SourceCode.png" style="zoom:40%" />
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/RunLoop-SourceCode.png" style="zoom:40%" />
|
||||
|
||||
Demo:
|
||||
|
||||
@@ -1151,7 +1151,7 @@ Demo:
|
||||
|
||||
2. 上面8>2,Runloop 处理 GCD Async To Main Quque
|
||||
|
||||
<img src="./../assets/RunLoopPerformTaskFromGCDMainQueue.png" style="zoom:25%" />
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/RunLoopPerformTaskFromGCDMainQueue.png" style="zoom:25%" />
|
||||
|
||||
|
||||
|
||||
@@ -1165,7 +1165,7 @@ Demo:
|
||||
|
||||
可以在 App 运行过程中,点击 Xcode 左下角的 debug 暂停按钮,可以看到 App 堆栈存在系统调用
|
||||
|
||||
<img src="./../assets/RunLoopSleepSystemCall.png" style="zoom:30%" />
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/RunLoopSleepSystemCall.png" style="zoom:30%" />
|
||||
|
||||
|
||||
|
||||
@@ -1647,7 +1647,7 @@ App 启动后,主线程 RunLoop 里注册了2个 Observer,其回调都是 `_
|
||||
|
||||
当界面的 Frame 改变,或者更改 UIView、CALayer 的层次时,或者调用了 UIView、CALayer 的 setNeedsLayout、setNeedsDisplay 方法后,这个 UIView、CALayer 会被标记为待处理(类比前端的 Virtual Dom Diff,标记为 dirty),并被提交到一个全局容器中。
|
||||
|
||||
苹果设计 UI 更新也是 RunLoop 的业务方,所以会注册一个 Obserger 监控 `kCFRunLoopBeforeWaiting`(将要休眠)和 `kCFRunLoopExit` (即将退出 RunLoop)状态,然后会执行 `_ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv()` 回调。内部会遍历所有待处理的 UIView、CALayer 以执行实际的绘制和渲染,更新 UI
|
||||
苹果设计 UI 更新也是 RunLoop 的业务方,所以会注册一个 Observer 监控 `kCFRunLoopBeforeWaiting`(将要休眠)和 `kCFRunLoopExit` (即将退出 RunLoop)状态,然后会执行 `_ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv()` 回调。内部会遍历所有待处理的 UIView、CALayer 以执行实际的绘制和渲染,更新 UI
|
||||
|
||||
|
||||
|
||||
@@ -1887,7 +1887,7 @@ main 方法内其实就是在执行 _selector。也就是在 NSThread 的初始
|
||||
|
||||
2. `[[NSRunLoop currentRunLoop] run]` api 换掉。查看系统说明,底层其实就是一个无限循环,循环内部不断调用 `runMode:beforeDate:`。下面也有建议,建议我们想销毁 RunLoop,可以替换 API,比如设置一个变量,标记是否需要结束 RunLoop
|
||||
|
||||
<img src="./../assets/RunLoop-RunIssue.png" style="zoom:45%" />
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/RunLoop-RunIssue.png" style="zoom:45%" />
|
||||
|
||||
改进代码如下
|
||||
|
||||
@@ -1995,7 +1995,7 @@ self.thread = [[LifeThread alloc] initWithBlock:^{
|
||||
|
||||
效果如下:
|
||||
|
||||
<img src="./../assets/RunLoopThreadKeepLive.png" style="zoom:30%" />
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/RunLoopThreadKeepLive.png" style="zoom:30%" />
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user