メッセージ間で実行ループを実行できるようにするには、NSTimer
または遅延実行を使用します。後者は次のとおりです。
- (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];
}
タイマーベースのソリューションの 1 つを次に示します。従うほうが簡単かもしれません。テキスト フィールドからテキスト フィールドの値を設定できます。
@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
プロパティを使用した、さらに優れた (よりクリーンな) タイマーベースのソリューションを次に示します。テキスト フィールドを Interface Builder のプロパティにバインドする必要があります (フィールドを選択し、⌘4 を押し、オブジェクトを選択currentNumber
し、バインド先のキーとして入力します)。
@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
プロパティ ベースのソリューションには、少なくとも 2 つの利点があります。
- オブジェクトは、テキスト フィールドについて知る必要はありません。(これは、テキスト フィールドであるビュー オブジェクトとは別のモデル オブジェクトです。)
- さらにテキスト フィールドを追加するには、IB でそれらを作成してバインドするだけです。TestNums クラスにコードを追加する必要はありません。