iOS高级开发工程师面试——RunLoop
iOS高级开发工程师面试——RunLoop
- 一、什么是 RunLoop? RunLoop 作用有哪些?
- 二、 app 如何接收到触摸事件的 ?
- 三、为什么只有主线程的RunLoop是开启的?
- 四、为什么只在主线程刷新 UI ?
- 五、PerformSelector和RunLoop的关系 ?
- 六、如何使线程保活?
- 七、子线程默认有RunLoop吗? RunLoop 创建和销毁的时机又是什么时候呢?
- 八、RunLoop有哪些 Mode 呢?滑动时发现定时器没有回调,是因为什么原因呢?
一、什么是 RunLoop? RunLoop 作用有哪些?
RunLoop
可以称之为运行循环,在程序运行过程中循环做一些事情,如果没有 RunLoop
程序执行完毕就会立即退出,有 RunLoop
程序会一直运行,并且时时刻刻在等待用户的输入操作。RunLoop
可以在需要的时候自己跑起来运行,在没有操作的时候就停下来休息。充分节省CPU资源,提高程序性能。
-
基本作用:
1. 保持程序持续运行。程序一启动就会开一个主线程,主线程一开起来就会跑一个主线程对应的RunLoop
,RunLoop
保证主线程不会被销毁,也就保证了程序的持续运行。2. 处理App中的各种事件(比如:触摸事件,定时器事件,Selector 事件等) 。
3. 节省CPU资源,提高程序性能。程序运行起来时,当什么操作都没有做的时候,
RunLoop
就告诉 CPU,现在没有事情做,我要去休息,这时 CPU 就会将其资源释放出来去做其他的事情,当有事情做的时候RunLoop
就会立马起来去做事情。
二、 app 如何接收到触摸事件的 ?
-
APP进程的
mach port
接收来自SpringBoard
的触摸事件,主线程的RunLoop
被唤醒,触发source1
回调。 -
source1
回调又触发了一个source0
回调,将接收到的IOHIDEvent
对象封装成UIEvent
对象,此时APP将正式开始对于触摸事件的响应。 -
source0
回调将触摸事件添加到UIApplication
的事件队列,当触摸事件出队后UIApplication
为触摸事件寻找最佳响应者。 -
寻找到最佳响应者之后,接下来的事情便是事件在响应链中传递和响应
那么事件响应链是如何
传递
的呢 ? 可简称为 “由父及子” 的过程,即:- 触摸事件的传递是从父控件传递到子控件
- 也就是从
UIApplicaiton
->window
->寻找处理事件的最合适的view
两个重要的方法:
// 获取响应 事件的视图,通过下面的方法判断触控点位置 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;// 判断触摸点是不是在这个view的坐标上。如果在坐标上,会分发事件给这个view的子 view。后每个子view重复以上步骤,直至最底层的一个合适的view。 - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;
那么事件响应链是如何响应
的呢?可简称为 “由子及父” 的过程,即:- 事件响应会先从底层最合适的
view
开始,然后随着上一步找到的链一层一层响应touch
事件。默认touch
事件会传递给上一层。 - 如果到了
viewController
的view
,就会传递给viewController
。 - 如果
viewController
不能处理,就会传递给UIWindow
。 - 如果
UIWindow
无法处理,就会传递给UIApplication
。 - 如果
UIApplication
无法处理,就会传递给UIApplicationDelegate
。 - 如果
UIApplicationDelegate
不能处理,则会丢弃该事件。
三、为什么只有主线程的RunLoop是开启的?
app启动前会调用main函数,具体如下:
int main(int argc, char * argv[]) {NSString * appDelegateClassName;@auto