3 Replies Latest reply: Feb 7, 2013 11:48 AM by xnav
ID Tech Level 1 Level 1 (0 points)

I want to start a background thread that can handle events. That is, one that can be used with performSelector or NSStream's scheduleInRunLoop.

I looked through the run loop document

http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Multithre ading/RunLoopManagement/RunLoopManagement.html

but couldn't find instruction to _start_ a new runloop. So I rolled my own NSThread subclass with the following main. It seems to be working for my purpose but is it correct? Or is there an easier way?

 

enum lockCondition {THREAD_NOT_ENDED, THREAD_HAS_ENDED};

@interface EventHandlingThread : NSThread {

    //Another thread can wait for this thread to stop by waiting on this lock. It is passed in from constructor.

    NSConditionLock *_joinLock;

    //run loop of this thread. To be exposed to other threads

    NSRunLoop       *_runloop;

}

-(void)main {

    //preamble

    [_joinLock lock];

    NSAutoreleasePool *arp = [[NSAutoreleasePool alloc] init];

 

    //prepare

    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];

    _runloop = runLoop;

      //schedule a timer so runMode won't stop immediately

    NSTimer *keepAliveTimer = [[NSTimer alloc] initWithFireDate:[NSDate distantFuture]

        interval:1e308 target:nil selector:nil userInfo:nil repeats:YES];

    [runLoop addTimer:keepAliveTimer forMode:NSDefaultRunLoopMode];

 

    //loop

    LOGD(@"loop: starting");

    while (1) {

        if ( [NSThread currentThread].isCancelled )

            break;

 

        [runLoop runMode:NSDefaultRunLoopMode beforeDate: [NSDate distantFuture]];

        LOGD(@"loop: runMode returned");

    }

    LOGD(@"loop: ended");

 

    //clean up

    [keepAliveTimer invalidate];

    [keepAliveTimer release];

 

    //postamble

    [arp release];

    [_joinLock unlockWithCondition:THREAD_HAS_ENDED];

}


iOS 6.1