当前位置:网站首页>Runloop principle (I)
Runloop principle (I)
2022-07-28 23:30:00 【i_ erlich】
The intention of this article : When you read it completely carefully , Yes runloop cognition , Will become you as a ios Part of the developer's subconscious
One 、 The official picture begins

Official document opening introduction
Run loops are part of the fundamental infrastructure associated with threads.
runloop Is part of the thread related infrastructure , To put it bluntly runloop Is inseparable from threads , Leave thread ,runloop There is no way to talk about
A run loop is an event processing loop that you use to schedule work and coordinate the receipt of incoming events.
runloop It's an event handling loop , You can use it to arrange your work , Handle the received events as a whole
The purpose of a run loop is to keep your thread busy when there is work to do and put your thread to sleep when there is none.
runloop Purpose - In order to achieve such an effect , Deal with work , Sleep without work
These words are enough , Answered three questions of philosophy WDP:What -> runloop What is it? ?Do -> runloop What's it for ?Purpose -> runloop Purpose ?
Two 、 Although the official English description is very obscure , But for accuracy , Let's explain the official instructions
( One ) runloop describe
runloop The management of is not completely automatic , You have to design thread code , Start at the right time runloop, Respond to received events .
Cocoa(NSRunLoop) and Core Foundation(CFRunLoop) Both provide runloop Object helps you configure and manage your own threads runloop; Your app doesn't need to show these runloop object
Each thread has an associated runloop object
The application framework will automatically set up and run on the main thread run loop , As part of the application startup process
Only child threads need to run explicitly runloop
( Two ) Next The official analyzed how you configured your application runloop
1) ideology
The thread enters the loop , Run the event handler , Respond to runloop Received events
runloop Control how - adopt while perhaps for loop To drive runloop, Run the event handler
runloop From two different source Receiving events : Input sources and Timer sources
Input sources Provide
asynchronousevent , event From other threads or processesTimer sources Provide
Syncevent , event Occur at a predetermined time or at repeated intervals

Input sources: runloop Object to perform runUntilDate: Method , then runloop sign out
Timer sources: Will not cause runloop sign out
runloop Received Input sources, Will trigger a notification
about Input Sources, If you want to deal with more , Then register yourself runloop The observer To receive this notice
- You can go through Core Foundation Configure in your thread runloop The observer
2)Run Loop Modes
runloop Mode, Generally speaking, two sets , Is to Monitored objects aggregate and want The object of the notification aggregate
Monitored objects , Of course it is Two kinds of Sources 了 , Input and Timer
- Why monitor , In fact, it can be understood as monitoring , Something came in , Just process the response
The object of the notification , Nature is to inform The observer
- In general , The event itself does not care when it is handled , Just wait runloop Handle , When you wait is when , But I can't stand meddling , For example, I want to print a message before handling the event You need to register observers to receive notifications
Each run runloop, To specify a mode Or use the default mode, In this way, only with the specified mode The associated sources( There are two kinds of source) Will be monitored , Same as mode The associated observers Will be informed
runloop Several kinds of mode
Default
- Default
Connection
- You should seldom use this mode
Modal
- Cocoa Use this pattern to identify events for the modal panel
Event tracking
- During mouse drag and other types of user interface interaction tracking ,Cocoa Through this mode To restrict incoming events
Common modes ( It's a little confusing , Take a closer look at )
- It's a collection ,Cocoa The default is aggregate ( perhaps group) [Default, Modal, Event tracking],Core Foundation The default is [Default]; If one Input Source And Default relation , Then if mode by Common modes, The same is true of Modal relation , Also with the Event tracking relation , Apple offers CFRunLoopAddCommonMode Method to add other mode
3)Input Sources
Input Sources Deliver asynchronous events to threads , Divided into two
be based on Port Of source monitor Mach ports , Automatically by the kernel signal
Customize source Monitor custom events , Manually by another thread signal
At any moment ,Modes Will affect Input sources
Usually ,runloop stay default mode Next run, You can also specify Customize modes
If Input sources Not in the current Association mode, Then it generates any event Will keep , until Input sources In relation mode
4)Timer Sources
Timer Sources Deliver events to your thread synchronously at a preset time in the future
although Timer Sources A time-based notification is generated , But this timer It is not a real-time mechanism
If Timer sources Associations that are not currently monitored mode, be timer Will not be triggered
If timer When triggered ,runloop Being implemented handler Handle , be timer Their own handler Processing will wait for the next time Come and execute
If runloop no run get up , be timer Will not be triggered
timer Reschedule yourself according to the planned time interval , Not based on the actual trigger time , Even if the trigger time is later than the plan
In other words, set 5 Second trigger once , from 0 Start , wait until 8 Seconds , Next time it will be 10 Second scheduling execution
If triggered , I have missed many 5 Second interval ,timer According to the planned time interval , Automatically empty the missed schedule interval , That is to say, I missed many 5 second , such as 4 individual 5 second , this 4 individual 5 Seconds , Only once
5)Run Loop Observers
Sources VS Runloop Observers
Sources When synchronous or asynchronous events occur Trigger
runloop observers stay runloop It is triggered when it executes to a special position
You can use runloop Observers Prepare your thread to handle a given event
You can also prepare the thread before it goes into sleep
You can take runloop Observers Associated with the following events
The entrance to the run loop.
【 Get into runloop】
When the run loop is about to process a timer.
【runloop About to deal with timer】
When the run loop is about to process an input source.
【runloop About to deal with input source】
When the run loop is about to go to sleep.
【runloop Going to sleep 】
When the run loop has woken up, but before it has processed the event that woke it up.
【runloop When awakened , But in runloop Before dealing with the event that wakes it 】
The exit from the run loop.
【 sign out runloop】
You can go through Core Foundation add to runloop Observers, According to the events you are interested in , Customize callback settings and Activities
Create a runloop Observer when , You can specify It's a one-off still Repetitive (once or repeatedly)
- once observer After triggering , Take yourself from runloop Remove
- repeatedly observer After triggering , Still attached to runloop in
6)runloop Event sequence
Event sequence :
Notify observers that the run loop has been entered.
notice observer Has entered runloop
Notify observers that any ready timers are about to fire.
notice observer About to deal with timer
Notify observers that any input sources that are not port based are about to fire.
notice observer About to deal with non based port Of input source
Fire any non-port-based input sources that are ready to fire.
notice observer Handle Not based on port Of input source
If a port-based input source is ready and waiting to fire, process the event immediately. Go to step 9.
If based on port Of input source has ready, Wait for trigger , Handle the event immediately . Execution steps 9
Notify observers that the thread is about to sleep.
notice observer The thread is about to sleep
Put the thread to sleep until one of the following events occurs:
Thread to sleep Until one of the following events occurs
An event arrives for a port-based input source.
be based on port Of input source The event came
A timer fires.
timer Trigger
The timeout value set for the run loop expires.
runloop Set timeout Be overdue
The run loop is explicitly woken up.
runloop Be explicitly awakened
Notify observers that the thread just woke up.
notice observer The thread is awakened
Process the pending event.
Handle pending events
If a user-defined timer fired, process the timer event and restart the loop. Go to step 2.
If user defined timer Trigger , Handle timer event , And restart runloop Jump 2
If an input source fired, deliver the event.
If input source Trigger , Delivery events
If the run loop was explicitly woken up but has not yet timed out, restart the loop. Go to step 2.
If runloop Be explicitly awakened , But it hasn't timed out yet , Then restart runloop Jump 2
Notify observers that the run loop has exited.
notice observer sign out runloop
because timer and input sources Of observer notice Before the event , So there is a time gap between the notice and the actual occurrence of the event
It can be used sleep and awake-from-sleep Notifications to help correlate the interval between actual events
because timer And other cyclical events are in runloop run Delivered when , Therefore, bypassing this cycle will interrupt the delivery of these events
7) When to use runloop
The main thread runloop Auto start , You don't need to actively call run
Sub thread
If you run a long-term task , Probably avoid starting runloop
The following situations start-up runloop
Use ports or custom input sources to communicate with other threads
Use port or Customize input sources Communicate with other threads
Use timers on the thread.
Use... In threads timers
Use any of the
performSelector… methods in a Cocoa application.Cocoa In the application Use whatever performSelector Method
Keep the thread around to perform periodic tasks
Keep the thread executing periodic tasks
8) Create a runloop observer
CFRunLoopObserverContext Structure
OK, the code has , Do a test , Now I use M1 The computer Simulator
here , The following console has no additional output , That is to say Printing stopped 44 Time
I don't do anything , The console is still quiet
This is the time I press a key casually from the keyboard ( Be careful : At this time, the simulator should be in the foreground ) The console print is appended to observer Callback 60 Time , Compared with the last time , Added 16 Time , Remember this difference 16
Next, the control is still too quiet
The console is quiet , And the simulator does nothing , No operation is triggered , This is not thread Sleep Well
We press any key , The console then prints , This is not thread Wake up the Well , The observer received runloop The notice of ,16 Time to inform , Specific information each time , We didn't print , Let's go ahead , Continue to analyze later
According to the preliminary test runloop, adopt Core Foundation, We registered a in the main thread runloop The observer , Set up observer Callback function , Successfully received runloop The notice of
At least, Let's check runloop The direction is to establish ,runloop Given a certain response notification information
(1) The main thread Runloop Observer Notice information
Because of my M1 xcode As soon as you look at the stack, it crashes , So use mine x86 mac, There are discrepancies in the printed information , I believe you can ignore
The following is a boserver Each notification stack information , The following is strictly in order , Please be patient









… kCFRunLoopoBeforeTimers
… kCFRunLoopBeforeSources

...... Next, the thread sleeps


activity -
- 0x20: kCFRunLoopBeforeWaiting
- 0x40: kCFRunLoopAfterWaiting
- 0x1: kCFRunLoopEntry
- 0x2: kCFRunLoopBeforeTimers
- 0x4: kCFRunLoopBeforeSources
- 0x80: kCFRunLoopExit
Register through the main thread observer, We got one runloop Sequence activity flow
You'll find that [runloop run] , kCRunLoopExit after , Right now kCFRunLoopEntry, That is to say runloop After entering , Basically, I won't quit , Because after quitting Right now entry 了 , If you are interested, you can test it yourself
This [runloop run]
(2)run vs runUntilDate
Used in the above test runloop run, After the thread sleeps , Click on the screen The console is not printed , That is to say touch The event did not wake up the thread
Is that really the case ?
At this time, the simulator is black ,view Not yet normal load Come out , Let's verify
We are threadMain Add... Before the end of the method A print

At this time, we found that [runloop run] The subsequent printing is not printed on the console , explain [runloop run] It directly blocks the execution of the following code
change to the use of sth. runloop runUntilDate:

Something different
The printing we added is running normally At this time, the execution of the following code is not blocked The window is not on a black background explain view Loaded normally
We also found that Before printing the statement , Last printed activity by 0x80, It is kCFRunLoopExit, That is to say runloop Out of the , So the subsequent printing can be executed normally
There is a detail to pay attention to
Thread hibernation , Press any key Additional print found observer Additional callback times Turn into
12Time , Remember the above16Next time- If you test it yourself , You'll find that ,activity It didn't show up kCFRunLoopExit
Since any key can also wake up threads ,observer You can also receive notifications , explain runloop It must be another entry 了 , This is the time observer The notification information that can be received is very limited Again entry I didn't receive your notice
This question , We have to rely on swift Foundation Source code Indirect speculation CoreFoundation Come to view the analysis
Sleep , Touch the screen ,observer Additional callback times Turn into
18Time , It means that the events are different It's bound to have an impact observer Notification callbacks are somewhat different
(3) to runloop runUntilDate Cycle many times

! Find out for the first time runloop runUntilDate after ,runloop sign out , Re execution runloop runUntilDate, Again exit
original runloop You can do this , These details In fact, I understand runloop The key to , Because there are some confused things Don't ponder these details carefully There is no way get To the
(4) Create a timer

Add one timer after , You'll find out , No more keys or touch, Console observer The notification callback will automatically print , in other words timer Will keep waking up threads
(5) Configure long declaration cycle threads
Configure for a long declaration cycle thread runloop when , It's best to add at least one Input Source To receive messages
Although you can attach only one timer Enter the running cycle , But once timer Trigger , It usually fails , This will lead to runloop sign out
Add a repeat timer You can make runloop Run longer , But it needs to be triggered regularly timer To wake up the thread , This is actually another form of polling
by comparison ,Input Source Waiting for events to happen , Keep the thread asleep before the event occurs
边栏推荐
- [radar] radar signal online sorting based on kernel clustering with matlab code
- Mgr.exe virus caused the startup program to fail
- Kotlin function nesting
- Istio微服务治理网格的全方面可视化监控(微服务架构展示、资源监控、流量监控、链路监控)
- 解决控制文件全部损坏的异常
- cnpm安装步骤
- Messages from students participating in the competition: memories of the 17th session
- 欲要让数字零售继续发挥作用,我们需要对数字零售赋予新的内涵和意义
- Subscript in swift
- It's settled! All products of Nezha s will be launched on July 31
猜你喜欢

Price for volume has encountered "six consecutive declines" in sales. Can Volvo, which is no longer safe, turn around?

c语言进阶篇:指针(二)

Mycms we media mall V3.6 release, compatible with micro engine application development (laravel framework)

这个胶水有多强呢?

There are four ways for Nacos to configure hot updates and multiple ways to read project configuration files, @value, @refreshscope, @nacosconfigurationproperties

【MySQL系列】 MySQL表的增删改查(进阶)

c语言进阶篇:指针(三)

MySQL数据库的基本概念以及MySQL8.0版本的部署(一)

1314_串口技术_RS232通信基础的信息

18张图,直观理解神经网络、流形和拓扑
随机推荐
Routeros limited DNS hijacking and check
行泊ADAS摄像头前装搭载同比增长54.15%,TOP10供应商领跑
【滤波跟踪】基于EKF、时差和频差定位实现目标跟踪附matlab代码
Advanced C language: pointer (2)
The applet vant webapp component is missing, and the referenced component reports an error
【雷达】基于核聚类实现雷达信号在线分选附matlab代码
After reading MySQL database advanced practice (SQL xiaoxuzhu)
JS small method
Xshell7, xftp7 personal free version official download, no need to crack, no activation, download and use
Sqlilabs-2 (breakthrough record)
18 diagrams, intuitive understanding of neural networks, manifolds and topologies
Messages from students participating in the competition: memories of the 17th session
Binary search tree
[C language] implementation of three piece chess games
pg_ Installation and use of RMAN "PostgreSQL"
Win11找不到DNS地址怎么办?Win11找不到DNS无法访问网页解决方法
High quality programming
WebView optimization
Elements in the middle (one article is enough)
The development mode of digital retail dominated by traffic is only the beginning



