table of Contents[-]
Definition of RunLoop
purpose
understanding
characteristic
RunLoop mechanism
RunLoop runtime call stack
RunLoop Supported Message Events
Run Loop Modes
Run Loop application practice RunLoop definition
When there is a need for continuous asynchronous tasks, we will create a separate thread with a controlled life cycle. RunLoop is a mechanism that controls the life cycle of a thread and receives events for processing.
RunLoop is the core mechanism of iOS event response and task processing. It runs through the entire iOS system.
Foundation: NSRunLoopCore Foundation: CFRunLoop core part, open source code, written in C language, cross platform
purpose
Power saving through RunLoop mechanism, smooth, fast response, good user experience
understanding
The process is a factory, the thread is a pipeline, and the Run Loop is the director of the pipeline. When the factory receives an order from a merchant and assigns it to the pipeline, the Run Loop starts the pipeline to make the pipeline move and produce the product; when the product is completed At this time, the Run Loop will temporarily stop the pipeline to save resources. RunLoop manages the pipeline so that the pipeline will not be destroyed by the factory because it is doing nothing; when the pipeline is not needed, the supervisor of RunLoop will be fired, that is, exit the thread and release all resources.
RunLoop is not an exclusive concept of the iOS platform. In multi-threaded programming on any platform, in order to control the thread's life cycle, receiving and processing asynchronous messages requires a loop mechanism similar to RunLoop. Android Looper is similar.
characteristic
The RunLoop of the main thread is automatically created when the application starts
Other threads need to start by themselves in this thread
Can't create RunLoop yourself
RunLoop is not thread-safe, so you need to avoid calling RunLoop of the current thread on other threads
RunLoop is responsible for managing autorelease pools
RunLoop handles message events, that is, input source events and timer events
RunLoop mechanism
Main thread (thread with RunLoop) Almost all functions are called from one of the following six functions:
CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION
CFRunloop is calling out to an abserver callback function
Used to report changes to the current status of RunLoop to the outside. Many mechanisms in the framework are triggered by RunLoopObserver, such as CAAnimation
CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK
CFRunloop is calling out to a block
Message notification, non-delay perform, dispatch call, block callback, KVO
CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE CFRunloop is servicing the main desipatch queue
CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION
CFRunloop is calling out to a timer callback function
Delayed perform, delayed dispatch call
CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION
CFRunloop is calling out to a source 0 perform function
Handle internal events of the App, and the App is responsible for management (trigger), such as UIEvent, CFSocket. Ordinary function call, system call
CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION
CFRunloop is calling out to a source 1 perform function
RunLoop and kernel management, Mach port driver, such as CFMachPort, CFMessagePort
RunLoop architecture
??
<喎? Http: //www.bkjia.com/kf/ware/vc/ "target =" _ blank "class =" keylink "> vcD4KPHVsPgo8bGk + CjxwPgpSdW5Mb29wINTL0NDKsTwvcD4KCjxwPgo8YSB0YXJnZXkb" http://www.bkjia.com /uploads/allimg/160402/041JJ260-1.jpg "target =" _ blank ">
There are six main states:
kCFRunLoopEntry-enter the runloop loop
kCFRunLoopBeforeTimers-handle callbacks before timing calls
kCFRunLoopBeforeSources-handle events from input sources
kCFRunLoopBeforeWaiting-runloop call before sleep
kCFRunLoopAfterWaiting-called after the runloop wakes up
kCFRunLoopExit-exit runloop
RunLoop runtime call stack
Main thread App runtime
The relationship between RunLoopObserver and Autorelease Pool
UIKit uses the RunLoopObserver to pop and push the Autorelease Pool between RunLoop Sleeps to release the Autorelease objects generated in this loop.
RunLoop Suspend and Wake
Specify the mach_port port for wake up
Call mach_msg to listen on the wake-up port. Before being awakened, the system kernel suspends this thread and stays in mach_msg_trap state.
After another thread sends the msg of this port to the kernel, the trap state is awakened, and RunLoop continues to work.
RunLoop Supported Message Events
RunLoop
Supports receiving and processing Input Source events, including:
The system's Mach Port event is a communication event custom input event
Supports accepting and processing timing source (Timer) events
Before starting RunLoop, you must add the input source event or timing source event to be monitored. Otherwise, calling [runloop run] will return directly without entering the loop to let the thread stay.
If no input source event or Timer event is added, the thread will always be idling in an infinite loop, it will always occupy the CPU time slice, and no reasonable allocation of resources is achieved. Without a while loop and without adding any input source or Timer thread, the thread will complete directly and be recycled by the system.
Run Loop Modes
Understand that Run Loop Mode is the type of product supported by the production line. The production line can only run in one mode at a time to produce a certain type of product. A message event is an order.
Cocoa defines four modes
Default: NSDefaultRunLoopMode, the default mode. When the Run Loop does not specify a Mode, the default is to run in the Default Mode.
Connection: NSConnectionReplyMode, which is used to listen to events that process network connection NSConnection
Modal: NSModalPanelRunLoopMode, Modal panel event for OS X
Event tracking: UITrackingRunLoopMode, drag event
Common mode: NSRunLoopCommonModes is a set of modes. When an event source is bound to this mode set, it is equivalent to each mode in the set.
RunLoop can use [acceptInputForMode: beforeDate:] and [runMode: beforeDate:] to specify the running mode for a period of time. If not specified, RunLoop will run under Default by default (continuously calling runMode: NSDefaultRunLoopMode beforDate :)
Start a timer on the main thread, and then drag UITableView or UIScrollView. The timer is not executed. This is because, for better user experience, the event tracking mode has the highest priority in the main thread. When the user drags the control, the Run Loop of the main thread runs in Event tracking Mode, and the created Timer is associated with Default Mode by default, so the system will not immediately execute the events received in Default Mode. Solution:
NSTimer*timer=[NSTimerscheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(timerFireMethod:)userInfo:nil
repeats:YES];
[[NSRunLoopmainRunLoop]addTimer:timerforMode:NSRunLoopCommonModes];
//or
[[NSRunLoopcurrentRunLoop]addTimer:timerforMode:UITrackingRunLoopMode];
[timerfire];
Run Loop application practice
Run Loop mainly has the following three application scenarios:
Maintain the life cycle of the thread, so that the thread does not exit automatically, and exit when isFinished is Yes.
NSRunLoop*runLoop=[NSRunLoopcurrentRunLoop];
[runLoopaddPort:[NSMachPortport]forMode:NSDefaultRunLoopMode];while(!self.isCancelled&&!self.isFinished){@autoreleasepool{
[runLooprunUntilDate:[NSDatedateWithTimeIntervalSinceNow:3]];
}
}
Create resident threads to perform tasks that will always exist. This thread has the same life cycle as the App
@autoreleasepool{
NSRunLoop*runLoop=[NSRunLoopcurrentRunLoop];
[runLoopaddPort:[NSMachPortport]forMode:NSDefaultRunLoopMode];
[runLooprun];
}
A thread that listens for an event or performs a task for a certain period of time
The following code executes onTimerFired: every 30s within 30 minutes. This kind of scene usually appears, for example, I need to continuously update certain data after a certain period of time after the application starts.
@autoreleasepool{NSRunLoop*runLoop=[NSRunLoopcurrentRunLoop];NSTimer*udpateTimer=[NSTimertimerWithTimeInterval:30
target:self
selector:@selector(onTimerFired:)userInfo:nil
repeats:YES];
[runLoopaddTimer:udpateTimerforMode:NSRunLoopCommonModes];
[runLooprunUntilDate:[NSDatedateWithTimeIntervalSinceNow:60*30]];
}
Creation of RunLoop in AFNetworking
+ (void) networkRequestThreadEntryPoint: (id) __ unusedobject {@autoreleasepool {[[NSThreadcurrentThread] setName: @ "AFNetworking"]; NSRunLoop * runLoop = [NSRunLoopcurrentRunLoop]; // This is mainly to monitor a port, the purpose is to make this Thread not Will recycle [runLoopaddPort: [NSMachPortport] forMode: NSDefaultRunLoopMode];
[runLooprun];}
}
+ (NSThread *) networkRequestThread {staticNSThread * _networkRequestThread = nil; staticdispatch_once_toncePredicate; dispatch_once (& oncePredicate, ^ {_ networkRequestThread = [[NSThreadalloc] initWithTarget: selfselector: @selector (networkRequestThreadEntryPoint:) object: nil]; [_ networkRequestThreadstart_);} ;
}