Please look at this code:
@interface myObject:NSObject
-(void)function:(id)param;
@end
@implementation myObject
-(void)function:(id)param
{
NSLog(@"BEFORE");
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:20]];
NSLog(@"AFTER");
}
@end
int main(int argc, char *argv[])
{
myObject *object = [[myObject alloc] init];
[NSThread detachNewThreadSelector:@selector(function:) toTarget:object withObject:nil];
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
The function
method is called but there's no 20 seconds pause. What should i do to make NSRunLoop
work in a detached thread?
Since you are running the function:
selector in a different thread, [NSRunLoop currentRunLoop]
is not the same as in the main thread.
Please see NSRunLoop reference:
If no input sources or timers are attached to the run loop, this method exits immediately
I guess that your run loop is empty, and therefore the "BEFORE" and "AFTER" logs will appear instantaneously.
A simple solution to your problem would be
@implementation myObject
-(void)function:(id)param
{
NSLog(@"BEFORE");
[[NSRunLoop currentRunLoop] addTimer:[NSTimer timerWithTimeInterval:20 selector:... repeats:NO] forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
NSLog(@"AFTER");
}
@end
In reality, you would probably put the code that logs "AFTER" in a new method that is called by your timer. In general, you do not need threads to do animations (unless you are doing something computationally expensive). If you are doing computationally expensive stuff, you should also look into using Grand Central Dispatch (GCD), which simplifies off-loading calculations on background threads and will handle the plumbing for you.