How to wait in NSThread until some event occur in iOS?

Bharath picture Bharath · Jul 31, 2013 · Viewed 15.1k times · Source

How to wait inside the NSThread until some event occur in iOS?

eg, We created a NSThread and started a thread loop. Inside the thread loop, there is condition to check whether the message queue has any messages. If there is a message, then it will call the corresponding method to do some operation, else it should wait until the message queue gets populated with a new message.

Is there any API or methods available to wait until some event occur?

For Example 

NSThread *thread = [NSThread alloc]....@selector(threadLoop)

- (void)threadLoop
{
   // Expecting some API or method that wait until some messages pushed into the message queue
   if (...) {

   }
}

Any help should be appreciated.

Answer

LombaX picture LombaX · Jul 31, 2013

You can use NSCondition. I attach example code "ready-for-test" in a ViewController

@interface ViewController ()

@property (strong, nonatomic) NSCondition *condition;
@property (strong, nonatomic) NSThread *aThread;

// use this property to indicate that you want to lock _aThread
@property (nonatomic) BOOL lock;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    // start with the thread locked, update the boolean var
    self.lock = YES;

    // create the NSCondition instance
    self.condition = [[NSCondition alloc]init];

    // create the thread and start
    self.aThread = [[NSThread alloc] initWithTarget:self selector:@selector(threadLoop) object:nil];
    [self.aThread start];

}

-(void)threadLoop
{
    while([[NSThread currentThread] isCancelled] == NO)
    {
        [self.condition lock];
        while(self.lock)
        {
            NSLog(@"Will Wait");
            [self.condition wait];

            // the "did wait" will be printed only when you have signaled the condition change in the sendNewEvent method
            NSLog(@"Did Wait");
        }

        // read your event from your event queue
        ...


        // lock the condition again
        self.lock = YES;
        [self.condition unlock];
    }

}

- (IBAction)sendNewEvent:(id)sender {
    [self.condition lock];
    // put the event in the queue
    ...


    self.lock = NO;
    [self.condition signal];
    [self.condition unlock];
}