Basic knowledge of

The concept of RunLoop

Runloop can be thought of as an event-driven circle. When we perform events, gestures, time responses, etc., we need listeners. This is where the concept of sources comes from.1. The input source 2. Time source

—- pseudocode is as follows:

while (true) {[[NSRunLoop currentRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate distantFuture]];
}
Copy the code

Note:

The main thread starts a Runloop by default,while the asynchronous thread does not. The while prevents the Runloop from sleeping, and the Runloop automatically starts sleeping when there is no “event source” to drive it

Input source

Includes three types: NSPort, custom source, performSelector: OnThread: delay

2.1 NSPort Port-based source

Cocoa and Core Foundation provide built-in support for port-based sources created using port-related objects and functions. In Cocoa you never have to create an input source directly. You simply create the port object and add it to the Run loop using the NSPort method. The port object handles creating and configuring the input source.

There are three types of NSPort: NSMessagePort (basically abandoned), NSMachPort, and NSSocketPort. The NSURLConnection in the system is based on NSSocketPort communication, so when using NSURLConnection in the background thread, you need to manually start the RunLoop, because the RunLoop in the background thread is not started by default.

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];// Temporarily not running
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];/ / use NSRunLoopCommonModes
[connection start];
Copy the code

You can use NSMachPort as a communication channel between threads. For example, when the main thread creates a child thread, it passes in an NSPort object, so that the main thread can communicate with the child thread. To achieve two-way communication, the child thread also needs to pass back an NSPort object to the main thread

2.2 Custom Sources

In Core Foundation applications, you must use CFRunLoopSourceRef type-dependent functions to create a custom input source, followed by a callback function to configure the input source. Core Fundation calls callbacks when appropriate to handle input events and clean up sources. Common touch, scroll events, and so on are such sources, implemented internally by the system. Normally we would not use this provenance, and the third case has met our needs

2.3 performSelector: OnThread

Cocoa provides input sources that can perform selectors in any thread. As with port-based sources, Perform Selector requests are serialized on the target thread, mitigating many of the synchronization problems that can easily be caused on a single thread. And unlike port-based sources, perform Selector automatically clears the Run loop when it executes. This method is simple and practical, and more widely used.

performSelectorOnMainThread:withObject:waitUntilDone:  
performSelectorOnMainThread:withObject:waitUntilDone:modes:

performSelector:onThread:withObject:waitUntilDone:  
performSelector:onThread:withObject:waitUntilDone:modes:

performSelector:withObject:afterDelay:  
performSelector:withObject:afterDelay:inModes:

cancelPreviousPerformRequestsWithTarget:  
cancelPreviousPerformRequestsWithTarget:selector:object:
Copy the code

The last two of these apis are to cancel a call in the current thread, and the other apis are to execute a specified @selector in the main thread or in a Run Loop under the current thread.

Time source

Note that the Timer generated at the beginning of scheduledTimerWith**** will automatically load the current RunLoop in default NSDefaultRunLoopMode. Other generated timers require you to manually add -addTimer:forMode to the Run Loop. It is important to note that the Timer firing does not cause the Run Loop to return.

[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
[[NSRunLoop currentRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate distantFuture]];
Copy the code

RunLoop observer

A CFRunLoopObserverRef object can be created to detect the working state of the RunLoop. It can detect the following events of the RunLoop: Run loop entry Run loop is about to start timing Run Loop is about to process input source Run Loop is about to sleep Run loop is woken up but terminates before the wake up event is executed

1. Run Loop Modes

Mode Name Description
Default NSDefaultRunLoopMode (Cocoa) kCFRunLoopDefaultMode (Core Foundation) By default, all operations are included, and this mode is used in most cases, the default running mode, except for events on NSConnection objects
Connection NSConnectionReplyMode (Cocoa) This mode is used to handle callback events for NSConnection
Modal NSModalPanelRunLoopMode (Cocoa) Modal mode, in which RunLoop only handles modal-related events
Common Modes NSRunLoopCommonModes (Cocoa) kCFRunLoopCommonModes (Core Foundation) This mode is used to configure group mode. If an input source is associated with this mode, the input source is associated with all modes in the group
Event Tracking NSEventTrackingRunLoopMode (Cocoa) This mode is used to handle window events, mouse events, etc

Note: NSRunLoopCommonModes is a set of commonly used modes, NSDefaultRunLoopMode, NSTaskDeathCheckMode, UITrackingRunLoopMode. The advantage of this mode is that if the asynchronous thread now has a timer started, Do not append in all runloop modes, just append once in NSRunLoopCommonModes

Reference connection:

IOS Multithreaded Programming Part 1/3 – NSThread & RunLoop 3 Run Loops 4.Cocoa Learn more about NSOperationQueue, NSRunLoop and Thread safety