一起养成写作习惯!这是我参与「日新计划 4 月更文挑战」的第1天 点击查看活动详情。

Runloop这个算是iOS开发者面试中最常见的问题之一了把,但是每次面试遇spring到这种问题都会菊花一苹果13紧,生怕回答数据结构实验报告的少了,数据结构教程第5版李春葆答案同时也怕回答的不够全面。所以针对这一问题,总结了一下几个级别的开发者需要知道点进行归纳。

初级(0-3年)

如果你要去面试初级,以现在的内卷的程度,这个问题基本数据结构教程第5版李春葆答案上是跑不了的面试技巧,想当年作者还是初级的时候,连runloop都不知道是什么。。。

Runloop 是什么

Runloop是通过内部维护的事件循环来对面试技巧事件/消息进行管理的一个对象

这里有两个重点

  1. 事件循环

  2. 事件/消息进行管理


什么是事件循环呢?
事件循环(状态切换)
 没有消息需要处理时,休眠以避免资源占用
    用户态——>内核态
有消息需要处理时,立刻被唤醒
    用户态<—— 内核态
什么是事件/消息进行管理呢?
RunLoop 通过 mach_msg()函数接收、发送消息来进行管理。
它的本质是调用函数 mach_msg_trap(),相当于是一个系统调用,会触发内核状态切换。
可以做到在有事做的时候做事,没事做的时候,会由用户态切换到内核态,避免资源浪费。
如何实现事件、消息的管理
mach_msg() 函数实际上是调用了一个 Mach 陷阱 (trap),
即函数mach_msg_trap(),陷阱这个概念在 Mach 中等同于系统调用。
当你在用户态调用 mach_msg_trap() 时会触发陷阱机制,切换到内核态;
内核态中内核实现的 mach_msg() 函数会完成实际的工作,

当面试官问Runloop时,想听到的答案是什么?

所以说 Runloop的核心就是一个 mach_msg(),RunLoop 调用这个函数去接收消息,如果没有别人发送 port 消息过来,内核会数据结构与算法将线程置于等待状态。例如你在模拟器里跑起一个 iOS 的 App,然后在 App 静止时点击暂停,你会看到主线程调用栈是停留数据结构严蔚敏在 mach_msg_trap() 这个地面试技巧方。

说了这苹果范冰冰么多,应该可以对初级iOS开发者提供一个比较系统的概念,如果手势密码你还数据结构与算法想卷的话,可以看继续往下看

中级(3-6年)

在这级别苹果手机里,需要知道的就不仅仅是Runloop是什么了,更应该面试常见问题及回答技巧知道其中的数据结构和实际springboot使用。

ps:卷的不能再卷了(╬ ‸ )

Runloop的数据结构

NSRunloop是CFRu手势识别nloop的封装,提供了面向对象的API

typedef struct __CFRunLoopMode *CFRunLoopModeRef;
struct __CFRunLoopMode {
    //...
    CFStringRef _name;
    //...
    CFMutableSetRef _sources0; // <Set>
    CFMutableSetRef _sources1;// <Set>
    CFMutableArrayRef _observers; // <Array>
    CFMutableArrayRef _timers; // <Array>
    //...
};
///CFRunLoop.h 类型重命名
typedef struct __CFRunLoop * CFRunLoopRef;
///CFRunLoop.c 结构体
struct __CFRunLoop {
    //..
    CFMutableSetRef _commonModes; // <Set> String UITrackingRunLoopMode/kCFRunLoopDefaultMode
    CFMutableSetRef _commonModeItems;// <Set> observer/source/timer
    CFRunLoopModeRef _currentMode; //当前运行的mode
    CFMutableSetRef _modes; //内置的modes;
    //...
};

CFRunloop

  • pthread (与线程一一对应)
  • currentMode (当前的运行模式)
  • mod手势es (集合 NSMutableSet <CFRunLoopMode *>)
  • commonModes(一个springmvc的工作原理存储了被标记为common modes的模式集合 【NSMutableSet <NSString *>】)
  • commonModeItems(它是一个集合, 集合里面有多个元素, 有多个Observer,有多个Timer,有多个Source
pthread

C语言线程对象

Ru数据结构教程第5版李春葆答案nlo数据结构题库op和线程的关系是,一一对应

currentMode

Runloop当前所处的模式 ,是CFRunLoopMode数据结构

modes
  • 一个Runloop有一个modes

  • 一个modes 是由多个CFRunLoopMode组成

  • 一个CFRunLoopMode是由 name/Sour苹果手机怎么录屏ce/Timer/Observer 组成

  • RunLoop 只能运行一个 Mspring框架ode苹果x,RunLoop 只会处理它当前 Mode 的事件面试常见问题及回答技巧

当面试官问Runloop时,想听到的答案是什么?

当面试官问Runloop时,想听到的答案是什么?

source — CFRunLoopSourceRe手势语f

  • Source0:只包含了一个回调(函数指针),它并不能主动触发事件。使用时,你需要先调用 CFRunLoopSourceSig面试常见问题及回答技巧nal(source),将这个 Source 标记为苹果手机待处理,然后手动调用 CFRun数据结构LoopWakeUp(runloop) 来唤醒 RunLoop,让其处理springmvc的工作原理这个事件。

  • Source1 :基于数据结构知识点总结mach_Port的,来自系统内核或者其他进程或线程的事件,可以主动唤醒休眠中的RunLoop(iOS里进程间通信数据结构与算法开发过程中我们一般不主动使用)。mach_port大家就理解成进程间相互发送手势变化消息的一种机制就好。

简单举个例子:一个APP在前台静止着,此时,用户用手指点击了手势舞视频一下APP界面,那么过程就是下面这样的:

我们触摸屏手势幕,先摸到硬件(屏幕),屏幕表面的事件会先包装成Event,Event先告诉Springsource(mach_port),source1唤醒RunLoop,然后将事件Event分发给source0,面试技巧和注意事项然后由source0来处理。

如果没有事件,也没有ti苹果mer,则run面试自我介绍一分钟loop就spring面试题会睡眠,如果有,则runloop就会被唤醒,然后跑一圈。

Observer — CFRunloopObserver

观察者可观测的时间点

  • kCFRunloopEntry (runlspring面试题oop准备启动)
  • kCFRunloopBeforeTimers (通知观察手势含义图解大全者,runloop将要对Timer的一些相关事件进行处理了)
  • kCFRunloopBeforeSources (将要处理一些Sources事件手势)
  • kCFRunloopBeforeWaiting( 即将要发生用户态到内核态的切换 用户态 —> 内核态)
  • kCFRunloopAfterWaiting (内核态—转—>用户态)
  • kCFRunloopExit (runloop退出通知)

这些可观察的时间点有时也可作为检测app卡顿的功能,但是实际使用也不太好用,这里就不展开细说了。

Timer — CFRunloopTimer

是基于时间的触发器,它和 NSTimer 是toll-free bridged 的,可以混用。其包含一个时间长度和一个回调(函数指针)。当其加入到 RunLoop 时,RunLoop会注册对应的时间点,当时间点到时,RunLoop会被唤醒以执行那个回调。

这个只做简单的了解,中级还用不到。。。

commonModes

在这里要先说一下 系统的提供的几个默认模式

- kCFRunLoopDefaultMode, App的默认运行模式,通常主线程是在这个运行模式下运行
- UITrackingRunLoopMode, 跟踪用户交互事件(用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他Mode影响)
- kCFRunLoopCommonModes, 伪模式,不是一种真正的运行模式
- UIInitializationRunLoopMode:在刚启动App时第进入的第一个Mode,启动完成后就不再使用
- GSEventReceiveRunLoopMode:接受系统内部事件,通常用不到

UIInitializationRunLoopModeGSEventRecei苹果7veRunLoopMode 平时用不到,这里就不说了

  • kCFRunLoopDefaultMode:一般a数据结构c语言版严蔚敏第二版答案pp啥都不操作时,currentMode 就是 kCFRunLoopDefaultMode。

  • UITra数据结构ckingRunLoopMode:当发生app与用户进行交互时,就会退出之前的mode,进入这个mode

  • kCFRunLoopCommonModes:用人话说就是一个标记mode,当某个mode打上NSRunLoopCommonModes标记时,就会是这个

再说回commonModes、它是一个集合,里面存储着被标记kCFRunLoopCommonModes的mode的name

我们来看看commonModes的数据结构

当面试官问Runloop时,想听到的答案是什么?

从图片可以看出,系统默认是将kCFRunLoopDefaultMo苹果8deUITrackingRun数据结构教程第5版李春葆答案LoopMod数据结构知识点总结e都放到co数据结构题库mmonModes中了.

所以说 某个苹果因不送充电器被判赔7000元mode可以将自己标记为为common,标记为 common 的 mode,都会被添加进 commonModes中.

commonModeItems

当前运行在commspring框架onModes面试问题大全及答案大全springboot面试题下的CFRunLoopSourceCFRunLoopObse手势识别rverCFRunLoopTimer

苹果官网解起来就是 kCFRunLoopDefaultMode 的 source1/timer/observspring翻译ers 和 UITrack数据结构知识点总结in苹果范冰冰gRunLoopMode 的 source1/timer/observers 都包含在 commonModeItems 里面

commonModes 里每多一个 mod数据结构知识点总结e ,commonModeItems 里就会多一组 sour面试自我介绍一分钟ce苹果手机1/timer/obser面试技巧和话术大全vers 。数据结构

事件循环的时间机制

我们通过一张图片来了解一下 runloop 是如何进行事件循环的

当面试官问Runloop时,想听到的答案是什么?

  1. mai面试自我介绍一分钟n函数—>UIApplicationMain
  2. 在U手势舞IApplicat苹果因不送充电器被判赔7000元ionMain中启动主线程的Runloop
  3. 即将进入Runloop(通知ospring翻译bserver)
  4. 将要处理timer、source0事件(通知observer)
  5. 处理source0事件
  6. 如果有source1事件要处理(跳转到10)
  7. 线程将要休眠(通知observe手势识别r)
  8. 休眠、等待唤醒(唤醒的方法:1 source1事件,2 Timer事件,3 外部手动唤醒)
  9. 线程刚被唤醒(通知observer)
  10. 处理唤手势识别醒时收到的消息
  11. 即将退出Runloop(通知obSpringserver)

高级(6年以上)

身为高级iOSer,需要知道应该就不仅仅是数据结构了,更应手势密码图案大全该知道是如何实现的springboot面试题,以及项目中在哪些方面有应用。

ps 卷王就是你了 (╯‵□′)╯︵┻━┻

mode是如何切换的

首先我们来说是,mode是如何切换的 例如:scrollView 由静止到滑动,是如何由Nspring框架SDefaultRunLoopMospring面试题de变为UITrackingRunLoopMode

首先 我们要了解一下 CFRunLoopRunSpecific

CFRunLoopRunSpecific 是启动 Ru面试技巧和注意事项nloop 和指定 Runloop 在那个mode下执行的mode。这个函数一般是操作系统进行mode的切换。

比如滑动面试自我介绍简单大方的时候,Runloop 会进入进入 UITrackingRunLoospring翻译pMode,而app启动的时候UIInitializationRunLoopMode

每一个modeSpring处理完成后,如果runloop没有退出,就会返回之前的mode,初始mode是defspringmvc的工作原理ault。

CFRunLoopRunSpecific 会保持前一次mode的状态属性(stopped和currentmode)然后发出即将要进入新的mode通知,然后进入__CFRunLoopRun(__CFRunLoopRun会创建一个循环),然后这个mo苹果13de运行结束后再发已退出mode通知。再恢复前一次的 stopped 和 currentmode

commonMode 的作用

在中级篇里,其实我们只是了解了 commonMode 的数据结构,但是还是没有完全了解 他springmvc的工作原理们的springboot面试题的作用是什么。

所以我们做已经烂大街的例子来说明一下,就是NSTimer定时器的添加

众所周知,NSTimer的创建,无论是通过init方式还是block的方式,如果不使用

[runLoop addTimer:timer forMode:xxx];

方法, time苹果13r会默认加入currentMode,也就是 kCFRunLo苹果8opDefaultMode

所以就会有一个问题,在一个 Tableview 上加入 NSTimer,当 Tablevspringcloudiew 滚动时,timer 的计时就不会生效。

原因就是 Tableview 的滚动 会让 runloop 切换手势UITrackingRunLoopMode,而 timer 没有加在 UITr面试技巧和注意事项ackingRunLoopMode 里面,所以这个timer 不会执行。

那怎么处理比较好呢苹果手机怎么录屏?就是把 timerspring面试题 关联到 NSRunLoopCommonModes 中,这面试自我介绍一分钟样,timer 就可以在 tableview 静止或滚动时,都会执行了。

看完这个问题,就会有疑问,为什么关联到NSRunLoopCommonModes 就会都执行呢?

理解起来就是 将这个 timer 打上一个 C数据结构与算法ommon 的标记。所有在 CommonModes 里的mode 都会去执行 打了 common 标记的事件。正常的时候 CommonModes只有 UITrackingRunLoopMode手势密码图案大全 kCFRunLoopDefaultMode,所以在这两个mode下,都会去执行 timer 事件。

Run Loop并不是在运行数据结构知识点总结NSRunLoop数据结构有哪些CommonModes,因为NSRunspringLoopCommonModes 是个Mode集合,而不是一个具体的M面试ode。我们面试技巧可以在添加事件源的时候使用 NSRunLoopCommonModes,只要Run Loop运行在NSRunLoopCommonModes中任何一个Mode,这个事件源都可以被springboot触发

ps:`CFRunLoopAddCommonMode` 方法可以向Common Modes中添加自定义mode。这里就不展开了

具体是如何通过代码同步的,就涉及到源码了,这里就spring漏洞不展开说明了,面试技巧和注意事项(毕数据结构竟是资深才能涉猎的。。。)

下面来说说 Runloop的使用场景

Autoreleas面试自我介绍简单大方ePool

App手势密码启动后,苹果在主线程 RunLoop 里注册了两个 Obs面试技巧erver,其回调都是 _wrapRunLoopWithAutoreleasePoolHandler()

第一个 Observer 监视的事件是 Entry(即将进入Loop),其回调内会调用 _面试技巧和话术大全objc_autoreleasePoolPush() 创建自动释放池。其 order 是-2147483647,优先级最高,保证创建释放池发生在其他所有回调之前。

第二个 Observer 监视了两个事件: Before苹果官网Waiting(准备进入休眠) 时调用_objc_autoreleasePoolPop()_objc_autoreleasePoolPush() 释放旧的池并创建新池;Exit(即将退出Loop) 时调用 _objc_autoreleaseP苹果手机oolPop() 来释放自动释放池。这个 Observer 的 order 是 2147483647,优先级最低,保证其释放池子发生在其他所有回调之后。

在主线程执行的代码,通常是面试常见问题及回答技巧写在诸如事件回调、Timer回调内的。这些回调会被 RunLspringoop 创建好的 AutoreleasePool 环绕着,所以不会出现内面试存泄漏,开发者也不必显示创建 Pool 了。

事件响应

苹果注册了一个 Source1 (基于数据结构c语言版严蔚敏第二版答案 mach port 的) 用来接收系统事件,其回调函数为 __IOHIDEvent苹果13SystemClientQueueCallback()。

当一个硬件事件(触摸/锁屏/摇晃等)发生手势含义图解大全后,首先由 IOKit.framework 生成一个 IOHIDEvent 事件并由 S面试自我介绍pringBoard 接收。这个过程的详细情况可以参考这里。SpringBoard 只接收按键(锁屏/静音等),触摸,加速,手势识别接近传感器等几种面试技巧和注意事项 Event,随后用 mach port 转发给需要的App进程。随后苹果注册的那个 Source1 就会触发回调,并调用 _UIApplicationHandleEventQueue() 进行应用内部的分发。

_UIApplicationHandleEventQueue() 会把 IOHIDEv苹果手机ent 处理并包装成 UIEvent 进行处理或分发,其中包括识别 UIGesture/处理屏幕旋转/发送给 UIWindow 等。通常事件比如 UIB苹果因不送充电器被判赔7000元utton 点击、touchesBegin/Move/E数据结构有哪些nd/Cancel 事件都是在这个回调中完成的。

手势识别

当上面的 _UIApplicationHandleEventQu手势识别eue() 识别了一个手势时,其首先会调用 Cancel 将当前的 touchesBegin/Move/End 系列回调打断。随后系统将对应的 UIG面试自我介绍简单大方e面试问题stureRecognizer 标记为待处理。

苹果注册了一个 Observer 监测 BeforeWa手势含义图解大全iting (Loop即将进入休眠) 事件,这个Observer的回调函数是 _苹果因不送充电器被判赔7000元UIGestureRecogspring是什么意思nizerUpdateObser手势舞ver(),其内部会获取所有刚被标记为待处理的 Gestu手势语reRecognizer,并执行GestureRecognizer的回调。

当有 UIGestureRecognizer 的变化(创建/销毁/状态改变)时,这个回调都会进行相应处苹果范冰冰理。

界面更新

当在操作 UI 时,比如改变了 Frame、更新了 U苹果12IView/CALayer 的层次时,或者手动调用了 UIView/CALayer 的 setNeedsLayout/se数据结构严蔚敏tNeedspring漏洞sDisplay方法后,这个 UIView/CALayer 就被手势舞教程视频慢动作标记为待处理,并被提交到一个全局的容器去。

苹果注册了一个 Observer 监听 BeforeWaiting(即将进入休眠)苹果官网 和 Exit (即将退数据结构与算法出Loop) 事件,回调数据结构题库去执行一个很长的函数: _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv()。这个函数里会遍历所有待处理的 UIView/CAlayer 以执行实际的绘制和调整,并更新 UI 界面。

按钮点击

首先是由那个Source1 接收IOHIDEvent,之后在回调 __IOHIDEventSystemClientQueuespringbootCallback() 内触发的 Source0,Source0 再触发的 _UIApplicationHandleEventQueue()。所以UIButton事件看到是在 Source0 内的。

当面试官问Runloop时,想听到的答案是什么?

结语

以上,便是Runloop的冰山一角,很多知识点都是简单的说了数据结构和作用,作者也只能管中窥豹一般的去用自己的理解和认知去解释,希望大家能海涵,如果有说的spring是什么意思不清楚或者不明白的,可以联系我,虽然我也不一定知道( ̄(エ) ̄)