When learning thread and run loop, I notice that some articles say: "Generally, a thread just exits once it has done its work." So there is necessity sometimes to create a so-called "immortal thread"(?? I don't know the exact term in English) using NSRunloop.
The question is HOW can I prove the statement "just exits once it has done its work"? I code like this
- (void)doSomethingOnThread {
// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// NSLog(@"I'm on thread %@", [NSThread currentThread]);
// });
NSThread *thread1 = [[NSThread alloc] initWithBlock:^{
NSLog(@"I'm on thread %@", [NSThread currentThread]);
}];
thread1.name = @"thread1";
[thread1 start];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(threadExitHandler:) name:NSThreadWillExitNotification object:nil];
}
- (void)threadExitHandler:(NSNotification *)noti {
NSLog(@"Thread will exit: %@", noti);
}
Well, the notification handler is not called.
So, [1]: How can I prove a thread exiting? [2]: What kinds of threads behave so?(I know the main thread will never exit, what about other thread? GCD threads, for example?)
If you want to visualize it, I might use the debugger. For example, I've set a breakpoint inside a
NSThreadsubclass and I see the thread listed in the left panel in Xcode:But if I have another breakpoint triggered one second after the
mainmethod finishes, I see the relevant “Thread will exit” message and my thread is no longer present :Or you could add a
NSLogstatement inside thedeallocmethod for yourNSThreadsubclass, and that also would demonstrate its deallocation. Or look for the subclass in the debug memory object graph.I'd suggest you add your observer for
NSThreadWillExitNotificationbefore you start your thread. Right now you have a race condition between the starting and exiting of this thread and the adding of the observer. FWIW, I do see the “Thread will exit” message.Unrelated, while it’s great to learn about threads and runloops, it has little practical use nowadays. It might be more useful to master GCD which gets us out of the weeds of threads and offers performance optimizations and a richer API for writing robust multi-threaded code.
In regards to whether GCD creates persistent threads or not, the answer is yes, but we're abstracted away from this detail. But one of GCD’s performance optimizations is that it manages a “pool” of threads for us, not constantly spinning up new threads and destroying them constantly for every dispatched block of code.
You might want to watch WWDC 2016’s Concurrent Programming With GCD in Swift 3. It walks through the relationship between queues, threads, and runloops.