RunLoop concept
RunLoop
It’s maintained internallyEvent Loop
Come to the rightEvent/Message
An object to manage- Sleep to avoid resource usage when there is no message processing; Wake up immediately when a message needs to be processed
- why
main
Function does not exit
int main(int argc, char * argv[]) {
@autoreleasepool {
returnUIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); }}Copy the code
UIApplicationMain internally turns on the main thread RunLoop by default and executes an infinite loop (not a simple for loop or while loop). UIApplicationMain never returns, receiving processing messages and waiting for sleep, so after running the program, It keeps running continuously
RunLoop structure
Source1
Based on:Port
Communication between threadsSource0
: Touch event,PerformSelector
Timer
Timer:Observer
: listener, used to listenRunLoop
The state of the
RunLoop and thread
- Threads and
RunLoop
Is one – to – one, the mapping is stored in a globalDictionary
In, threads act askey
.RunLoop
As avalue
- Self-created threads are disabled by default
RunLoop
the runloop
Is created on the first fetch and destroyed at the end of the thread- For the main thread,
runloop
It is created by default as soon as the program starts - For child threads,
runloop
It is lazy to load and is only created when we use it, so take care when using a timer on a child thread: make sure that the child thread isrunloop
Was created, or the timer will not be called back
- How do I create a resident thread
- Start one for the current thread
RunLoop
(First call[NSRunLoop currentRunLoop]
Method is actually created firstRunLoop
) - To the current
RunLoop
Add aPort/Source
Such as maintainingRunLoop
Event loop (ifRunLoop
themode
In aitem
All have no,RunLoop
Will quit) - Start the
RunLoop
@autoreleasepool {
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
[runLoop run];
}
Copy the code
- Print the sequence of the following code
NSLog(@"1");
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"2");
[self performSelector:@selector(test) withObject:nil afterDelay:10];
NSLog(@"3");
});
NSLog(@"4");
- (void)test{
NSLog(@"5");
}
Copy the code
If an afterDelay function is created, an NSTimer will be created internally and added to the current thread’s RunLoop. If the current thread does not have RunLoop enabled, the method will fail.
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"2");
[[NSRunLoop currentRunLoop] run];
[self performSelector:@selector(test) withObject:nil afterDelay:10];
NSLog(@"3");
});
Copy the code
The test method is still not executed because: If the mode of the RunLoop has no item, the RunLoop will exit. That is, after calling RunLoop’s run method, the RunLoop will exit anyway, since no item has been added to its mode to maintain the RunLoop’s event loop, so we start RunLoop ourselves. Be sure to add item after
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"2");
[self performSelector:@selector(test) withObject:nil afterDelay:10];
[[NSRunLoop currentRunLoop] run];
NSLog(@"3");
});
Copy the code
Attached: my blog address