I am trying to understand the concept of RunLoops. I have read Apple developer's guide on RunLoops and to some extent I have understood the concept of RunLoops. To make my concept more clearer I wrote a very simple code which uses RunLoops in it. The code can be seen below.
- (void)viewDidLoad
{
[super viewDidLoad];
thread = [[NSThread alloc] initWithTarget:self selector:@selector(testMethod) object:nil];
[thread start];
}
- (void)testMethod {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSLog(@"Thread Entered");
NSMachPort* dummyPort = [[NSMachPort alloc] init];
[[NSRunLoop currentRunLoop] addPort:dummyPort forMode:NSDefaultRunLoopMode];
while(!exitThread) {
NSLog(@"Thread did some work");
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
[[NSRunLoop currentRunLoop]
removePort:dummyPort
forMode:NSDefaultRunLoopMode];
[dummyPort release];
NSLog(@"Thread Exited");
[pool drain];
}
- (IBAction)doDomeWorkOnBackgroundThread:(id)sender {
[self performSelector:@selector(dummyMethod) onThread:thread withObject:nil waitUntilDone:NO];
}
- (IBAction)exitThread:(id)sender {
[self performSelector:@selector(exitBackgroundThread) onThread:thread withObject:nil waitUntilDone:NO];
}
- (void)exitBackgroundThread {
exitThread = YES;
}
- (void)dummyMethod {
//Empty
}
In above code I am creating a background thread and on that background thread I am calling function testMethod
. Inside testmethod
I am running a while which checks for BOOL variable exitThread
and runs the background thread's RunLoop using the - (BOOL)runMode: beforeDate:
method of NSRunLoop.
There are two IBActions which are attached to two buttons. As the name of the IBActions suggest one of them is to exitThread
and other one is to wake up the thread and execute NSLog statement written in the while loop.
The above code runs just as I expected. Whenever doDomeWorkOnBackgroundThread
method is executed thread wakes up from its runloop,performs the next iteration of the while loop, check for BOOL variable exitThread
and on finding it value as false goes inside the while loop and executes the NSlog statement.
Similarly When exitThread:
method is executed the exitThread
variable is set to true which causes the while loop and the thread to exit.
However I need few more clarifications :
1) If instead of using runMode: beforeDate:
in the while loop , I use run
or runUntilDate:
method of NSRunLoop, then the thread is never exited when exitThread:
method is executed. The exitBackgroundThread method is called on the background thread but the while loop never performs it's next iteration(as it does when I use runMode: beforeDate:
) and hence the thread is never exited.
2) I tried changing exitBackgroundThread
method to
- (void)exitBackgroundThread {
exitThread = YES;
CFRunLoopStop(CFRunLoopGetCurrent());
}
Since exitBackgroundThread
is executed on background thread CFRunLoopGetCurrent() should give the RunLoop of background thread. So this should ideally stop the run loop of the background thread regardless of whatever method of NSRunLoop I am using to start the RunLoop. So in any case thread must exit on call of above function. But it is just not happening.
I know I am missing something here and I am doing a fair amount of googling on my part to find answer to this question but just cant seem to find the right answer.
**EDIT
I have found this question which is very similar to my first query. It clears my first doubt to much extent.