Main event loop

本文深入探讨了iOS应用程序事件循环的工作原理,包括事件处理流程、事件队列的使用及核心对象如何响应事件和更新用户界面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

In the main event loop, an application continuously routes incoming events to objects for handling and, as a result of that handling, updates its appearance and state. An event loop is simply a run loop: an event-processing loop for scheduling work and coordinating the receipt of events from various input sources attached to the run loop. Every thread has access to a run loop(每个线程访问一个运行循环). In all but the main thread, the run loop must be configured and run manually by your code(除了主线程外在每个线程中,运行循环必须用你的代码手动设置并运行). In Cocoa applications, the run loop for the main thread—the main event loop—is run automatically by the application object. What distinguishes the main event loop is that its primary input source receives events from the operating system that are generated by user actions—for example, tapping a view or entering text using a keyboard.

The Application Object Gets and Dispatches Events

Just after an application is launched, it sets up the infrastructure for the main event loop. It establishes a connection with those underlying system components that are responsible for the delivery of low-level user events. The application receives these events through an input source installed in the main thread’s run loop. Because the application must handle each event separately, in order of its arrival, these low-level events are placed in a first-in first-out event queue.

Once the initial user interface is on the screen, the application is thereafter driven by external events. The application object obtains the topmost object in the event queue, converts it to an event object (UIEvent on iOS, NSEvent on Mac OS X), and dispatches it to other objects in the application for handling. When the call that dispatched the event returns, the application fetches the next object in the queue and dispatches it. It continues doing this until the application terminates.

Core Objects Respond to Events and Draw the User Interface

When an application is launched, it also sets up a core group of objects that are responsible for drawing the user interface and handling events. These core objects include windows and various kinds of views. When the application object gets an event from the event queue, it dispatches it to the window in which the user event occurred. The window sends the event to the view that is the most appropriate handler for it:

  • For multitouch and mouse events, the view is the one under the touch or mouse pointer.

  • For keyboard, motion, and other events, the view is the first responder.

If this initial view does not handle the event, it can pass it to other views in the application via the responder chain.

In handling the event, the view often initiates a series of actions that modify the appearance of the application and update the application’s state and data. When these actions have been completed, control returns to the application, which fetches the next event from the event queue.

### FreeRTOS 中事件循环的实现与用法 FreeRTOS 的事件循环机制通常通过队列 (Queue) 和信号量 (Semaphore) 来实现任务间的通信和同步。以下是关于 FreeRTOS 事件循环的具体实现与用法: #### 队列用于消息传递 在 FreeRTOS 中,`xQueueHandle` 是一种数据结构,允许不同任务之间发送和接收消息。创建一个队列可以通过 `xQueueCreate()` 函数完成[^1]。 ```c // 创建一个队列,能够存储最多10条消息,每条消息大小为 sizeof(uint32_t) xQueueHandle xQueue = xQueueCreate(10, sizeof(uint32_t)); ``` 当需要向队列中写入数据时,可以调用 `xQueueSend()` 或其阻塞版本;而读取则使用 `xQueueReceive()`。 ```c uint32_t ulVarToSend = 42; // 向队列发送一条消息 if (xQueueSend(xQueue, &ulVarToSend, portMAX_DELAY) != pdPASS) { // 发送失败处理逻辑 } // 接收来自队列的消息 uint32_t ulReceivedValue; if (xQueueReceive(xQueue, &ulReceivedValue, portMAX_DELAY) == pdTRUE) { // 处理接收到的数据 } ``` #### 使用信号量进行同步 除了队列外,FreeRTOS 提供二值信号量 (`Binary Semaphore`) 和计数型信号量 (`Counting Semaphore`) 实现任务间同步操作[^2]。 - **二值信号量**: 表示资源存在与否的状态标志位。 - **计数型信号量**: 跟踪可用资源的数量。 下面是一个简单的例子展示如何利用二值信号量控制两个任务之间的执行顺序: ```c xSemaphoreHandle xBinarySemaphore; void vTaskA(void *pvParameters){ while(1){ // 执行某些工作... // 给另一个任务发信号 xSemaphoreGive(xBinarySemaphore); vTaskDelay(pdMS_TO_TICKS(100)); // 延迟一段时间再继续 } } void vTaskB(void *pvParameters){ while(1){ // 等待来自 Task A 的信号 if (xSemaphoreTake(xBinarySemaphore, portMAX_DELAY) == pdTRUE){ // 收到信号后执行特定的工作... } } } int main(){ xBinarySemaphore = xSemaphoreCreateBinary(); xTaskCreate(vTaskA,"TaskA",configMINIMAL_STACK_SIZE,NULL,priority,&pxCreatedTask); xTaskCreate(vTaskB,"TaskB",configMINIMAL_STACK_SIZE,NULL,priority,&pxCreatedTask); vTaskStartScheduler(); return 0; } ``` 上述代码片段展示了如何设置基本的任务交互模式——其中一个任务等待直到它被其他任务唤醒为止。 #### 时间片轮转调度 FreeRTOS 默认采用基于优先级的时间片轮转算法来管理多个同级别任务共享 CPU 时间的情况。这意味着即使没有显式的“事件循环”,只要定义好各任务及其优先级关系,系统会自动按照设定好的规则切换运行中的进程。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值