简体   繁体   中英

NSTimer from secondary NSThread doesn't work

As per the documentation of Run Loop if there is any input source NSThread will be running otherwise it will go to sleep. I configured the timer same as provided under "Configuring Timer Sources" in above link but its not triggering. I am using below code.

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    [NSThread detachNewThreadSelector:@selector(testOnThread) toTarget:self withObject:nil];
}

- (void) testThread
{

    NSLog(@"Test");
}


-(void)testOnThread
{
    @autoreleasepool {

        NSRunLoop* myRunLoop = [NSRunLoop currentRunLoop];

        // Create and schedule the first timer.
        NSDate* futureDate = [NSDate dateWithTimeIntervalSinceNow:1.0];
        NSTimer* myTimer = [[NSTimer alloc] initWithFireDate:futureDate
                                                    interval:0.1
                                                      target:self
                                                    selector:@selector(testThread)
                                                    userInfo:nil
                                                     repeats:YES];
        [myRunLoop addTimer:myTimer forMode:NSDefaultRunLoopMode];
    }
}

Above code never prints "Test".

But timer is firing every time if I put [[NSRunLoop currentRunLoop] run]; at the end of -(void)testOnThread methods it works fine( Stackoverflow Question ). My query is if we are already providing timer input Source to run loop than what is the need to explicitly start it using [[NSRunLoop currentRunLoop] run];

I'll let others answer the question why you have to run the runloop yourself. But I'd like to suggest an alternative:

If you want to run timer on background thread, using dispatch timer is easiest, IMHO, with no runloop required at all. Just define timer property:

@property (nonatomic, strong) dispatch_source_t timer;

And then schedule the timer to run on a custom queue:

dispatch_queue_t queue = dispatch_queue_create("com.domain.app.timer", 0);
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(self.timer, dispatch_walltime(NULL, 0), 20ull * NSEC_PER_SEC, 1ull * NSEC_PER_SEC);

dispatch_source_set_event_handler(timer, ^{
    // code to be performed periodically on background thread here
});

dispatch_resume(self.timer);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM