3

私はObjective-Cが初めてなので、おそらくこれには簡単な解決策があります。

数値を増やしたいのですが、各反復をラベルに表示します。(たとえば、1、2、3、4、5... が時間間隔で表示されます)。

私は試した:

#import "testNums.h"

@implementation testNums
- (IBAction)start:(id)sender {
    int i;
    for(i = 0; i < 10; ++i)
    {
        [outputNum setIntValue:i];
        sleep(1);
    }
}
@end

9 秒間待ってから (どうやらフリーズしたようです)、テキスト ボックスに 9 と表示されただけです。

4

2 に答える 2

6

メッセージ間で実行ループを実行できるようにするには、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 つの利点があります。

  1. オブジェクトは、テキスト フィールドについて知る必要はありません。(これは、テキスト フィールドであるビュー オブジェクトとは別のモデル オブジェクトです。)
  2. さらにテキスト フィールドを追加するには、IB でそれらを作成してバインドするだけです。TestNums クラスにコードを追加する必要はありません。
于 2008-10-26T07:14:51.837 に答える
4

はい、それはあなたがそうするように言ったからです。グラフィックは、メインの実行ループが自由に表示できるようになるまで、実際には更新されません。NSTimer必要なことを行うには、またはそのような方法を使用する必要があります。

より良い質問は、なぜこれをやりたいのかということかもしれません。

于 2008-10-26T05:47:25.053 に答える