问题
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;
}
回答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";
}
回答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.
回答3:
This is a classic issue with virtually all GUI programming toolkits. If you're sleeping on the event-handling thread, then that thread is tied up, and it can't update the screen. If you need to do ongoing work which periodically updates the screen, then you must do that work in a separate thread; that's what you must do here.
回答4:
As already mentioned, blocking the main thread is probably not what you want to do. Instead of trying to stop your app from doing anything, including redrawing the screen or responding to touches, for 5 seconds think about the problem from a different angle. Create a NSTimer to schedule a method call 5 seconds in the future and let your app keep running while you wait for that timer to fire.
来源:https://stackoverflow.com/questions/5834062/calling-sleep5-and-updating-text-field-not-working