views:

125

answers:

4

Hi guys,

i'm coding a small app for the iphone (just for fun)

what i want:

if i press the "update" button:

  • send something to the server
  • parse the answer of the server
  • update the content of some labels on the screen
  • show the answer
  • play a system sound //using the audio toolbox
  • sleep some secods, just enough to finish the previos system sound call
  • do other stuff
  • end

actually, everything works but... for some reason, the label content is updated at the end of the method / callback / function that is called when pressed the "update" button.

what am i doing wrong? thanks!

some code:

-(void) playASound: (NSString *) file {

    //Get the filename of the sound file:
    NSString *path = [NSString stringWithFormat:@"%@/%@",
                      [[NSBundle mainBundle] resourcePath],
                      file];

    SystemSoundID soundID;
    //Get a URL for the sound file
    NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
    AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
    //play the file
    AudioServicesPlaySystemSound(soundID);
}

- (IBAction)update: (id) sender{
    BOOL error=[self sendContent];
    if ( error == NO ){
        result.text=[self parseContent];
        [self playSound:@"ready"];
        sleep(4);
        ....
    }
// here is updated the gui
}
+1  A: 

You don't want to use sleep there. Sleep stops the whole process from continuing that's why your label gets updated only at the end of the function. I'd recommend either using NSTimer or performSelector:withObject:afterDelay: (see here).

EightyEight
EightyEight thanks for the explanation and the link :-)
subzero
+2  A: 

The GUI is displayed by the runloop. The loop will not reach its next iteration until your method is done executing. Therefore, your method blocks the view from updating. Either use a background thread or a timer.

Chuck
Or just don't sleep.
tc.
@Chuck: ok, thanks for the explanation, i will try with a thread.@tc: if i do that, since the audio stuff is async, the code will continue.. so, imagine: the game (my app is a game) will start before you listen the instructions...
subzero
A: 

What about performing the [self sendContent] call in a separate thread?

Santa
no, it's a function that just sends a bunch of data to the server, it's sync.
subzero
+1  A: 

This is because you have blocked the main thread when you sleep. UI can only be drawn on the main thread.

A solution is to use [NSTimer scheduledTimerWithTimeInterval:X_SEC target:self selector:@selector(doOtherStuff) userInfo:nil repeats:NO] in place of sleep and do other stuff.

samwize
samwize, thanks!
subzero