To allow the run loop to run between messages, use an NSTimer
or delayed perform. Here's the latter:
- (IBAction) start:(id)sender {
[self performSelector:@selector(updateTextFieldWithNumber:) withObject:[NSNumber numberWithInt:0] afterDelay:1.0];
}
- (void) updateTextFieldWithNumber:(NSNumber *)num {
int i = [num intValue];
[outputField setIntValue:i];
if (i < 10)
[self performSelector:@selector(updateTextFieldWithNumber:) withObject:[NSNumber numberWithInt:++i] afterDelay:1.0];
}
Here's one timer-based solution. You may find it easier to follow. You could set the text field's value from the text field:
@interface TestNums: NSObject
{
IBOutlet NSTextField *outputField;
NSTimer *timer;
int currentNumber;
}
@end
@implementation TestNums
- (IBAction) start:(id)sender {
timer = [[NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(updateTextField:)
userInfo:nil
repeats:YES] retain];
//Set the field's value immediately to 0
currentNumber = 0;
[outputField setIntValue:currentNumber];
}
- (void) updateTextField:(NSTimer *)timer {
[outputField setIntValue:++currentNumber];
}
@end
Here's an even better (cleaner) timer-based solution, using a property. You'll need to bind the text field to the property in Interface Builder (select the field, press ⌘4, choose your object, and enter currentNumber
as the key to bind to).
@interface TestNums: NSObject
{
//NOTE: No outlet this time.
NSTimer *timer;
int currentNumber;
}
@property int currentNumber;
@end
@implementation TestNums
@synthesize currentNumber;
- (IBAction) start:(id)sender {
timer = [[NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(updateTextField:)
userInfo:nil
repeats:YES] retain];
//Set the field's value immediately to 0
self.currentNumber = 0;
}
- (void) updateTextField:(NSTimer *)timer {
self.currentNumber = ++currentNumber;
}
@end
The property-based solution has at least two advantages:
- Your object doesn't need to know about the text field. (It is a model object, separate from the view object that is the text field.)
- To add more text fields, you simply create and bind them in IB. You don't have to add any code to the TestNums class.