4

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?

Atulkumar V. Jain
  • 5,102
  • 9
  • 44
  • 61
Andrey Chernukha
  • 21,488
  • 17
  • 97
  • 161

1 Answers1

4

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.

Krumelur
  • 31,081
  • 7
  • 77
  • 119
  • Can you give me a hint about how to make my run loop not empty? – Andrey Chernukha Mar 22 '12 at 10:06
  • One way is to schedule a timer on the run loop, but what are you trying to accomplish? Maybe using a run loop is not the best way to solve your problem if this is the case? – Krumelur Mar 22 '12 at 10:07
  • What are you trying to accomplish by accessing the thread's run loop? – FluffulousChimp Mar 22 '12 at 10:07
  • what i'm trying to achieve is to make an animation's delegate method (-(void)animationDidStart:(CAAnimation *)anim) called. I want animations to be performed in a separate thread. Animations are executed each three seconds so i need a pause. But when i use [NSThread sleepForTimeInterval] delegate method is not called. – Andrey Chernukha Mar 22 '12 at 10:11