Calling sleep(5); and updating text field not working

I'm trying to sleep a method (see below), but rather than the textLabel changing from the value of myTextLabelString, waiting 5 seconds, changing to "sleep 5 worked", waiting 5 seconds and finally changing to "sleep 5 worked second time round".... it just goes from the value of myTextLabelString, waits 10 seconds, and then changes to "sleep 5 worked second time round".

- (void)textLabelChanger:(id)sender {

    NSString *myTextLabelString = [NSString stringWithFormat:@"%d", gameCountDown];    

    textLabel.text=myTextLabelString;
    sleep(5);
    textLabel.text=@"sleep 5 worked";
    sleep(5);
    textLabel.text=@"sleep 5 worked second time round";
    return;
}

Solution 1:

This will probably provide the result that you seek:

-(void)textLabelChanger:(id)sender
{
    NSString *myTextLabelString = [NSString stringWithFormat:@"%d", gameCountDown];    
    textLabel.text=myTextLabelString;

    [self performSelector:@selector(updateTextLabelWithString:) withObject:@"sleep 5 worked" afterDelay:5.0];
    [self performSelector:@selector(updateTextLabelWithString:) withObject:@"sleep 5 worked second time round" afterDelay:10.0];
}

-(void)updateTextLabelWithString:(NSString*)theString
{
    textLabel.text=theString;
}

There are plenty of ways to do this. Instead of having a single updateTextLabelWithString that you call twice with different delays, you could have a doFirstTextUpdate that writes the "sleep 5 worked" and then calls another selector like doSecondTextUpdate using the same [self performSelector:] technique after another 5 second delay.

It's exceedingly rare that you'll need to use the sleep() method with Objective-C.

-(void)textLabelChanger:(id)sender
{
    NSString *myTextLabelString = [NSString stringWithFormat:@"%d", gameCountDown];    
    textLabel.text=myTextLabelString;

    [self performSelector:@selector(firstUpdate) withObject:nil afterDelay:5.0];
}
-(void)firstUpdate
{
    textLabel.text = @"sleep 5 worked";
    [self performSelector:@selector(secondUpdate) withObject:nil afterDelay:5.0];
}
-(void)secondUpdate
{
    textLabel.text = @"sleep 5 worked second time round";
}

Solution 2:

Changes to UIKit components usually don't take effect until you drop out back to the runloop. Since you never intentionally block the main thread (and, I assume, your code is just a sleep test rather than something you'd actually want to do), that's not normally an issue.

Try NSLog in place of setting the 'text' property if you really want to verify that sleep is working (all logs have a timestamp), use performSelector:afterDelay: if you want something to occur on the main thread after a pause.