4

カウントダウンを表示するラベルを更新するタイマーを使用して RunLoop を作成しました。カウントダウンがゼロになったら RunLoop を停止する必要があります。タイマーが正常に終了した場合は、runUntilDate を使用できます。日付は現在の日付 + カウントダウンの時間です。問題は、ユーザーがカウントダウンが完了する前にボタンからキャンセルした場合です。RunLoop にキャンセル ボタン アクションから停止するように指示する方法がわかりません。RunLoop のコードは次のとおりです。

    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
                            [self methodSignatureForSelector:@selector(updateCountdownLabel:)]];
[invocation setTarget:self];
[invocation setSelector:@selector(updateCountdownLabel:)];
[[NSRunLoop mainRunLoop] addTimer:[NSTimer timerWithTimeInterval:1 invocation:invocation repeats:YES] forMode:NSRunLoopCommonModes];

このメソッドは、各ループで 1 ずつ減らすようにラベルに指示するだけです。

キャンセル ボタンにラベルをゼロに変更するように指示し、実行ループ セレクターに値がゼロかどうかをチェックさせることはできますが、RunLoop 自体のセレクターに停止を指示することはできますか?

cancelPerformSelector:target:argument:

cancelPerformSelectorsWithTarget:

これらは私が見つけた最も近いものですが、RunLoops 独自のセレクター内からは機能しないようです。少なくとも、私が試した方法では機能しません。

基本的に、RunLoopに停止するようにボタンに指示するか、何らかの方法で独自のセレクターからRunLoopを停止する必要があります。

ありがとう。

4

1 に答える 1

13

実行ループを作成していません。メインの実行ループで開始するようにタイマーをスケジュールしました。

NSTimer実行ループでタイマーをスケジュールする前に、作成したオブジェクトをインスタンス変数として保存する必要があります。

メソッドでは、updateCountdownLabel:終了条件が満たさ-invalidateれたら、タイマー インスタンスを呼び出すだけです。これにより、実行ループからタイマーが削除されます。保持されていないため、解放されます。

NSTimerセレクターベースではなくセレクターベースを使用するようにメソッドを更新しましたNSInvocation。これは、コールバック メソッドのシグネチャが期待どおりに定義されていることを意味します。また、NSTimerオブジェクトを ivarに格納する必要もありません。

- (void)startCountDown
{

    NSTimer* timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(updateCountdownLabel:) userInfo:nil repeats:YES]
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}


- (void)updateCountdownLabel:(NSTImer*)timer
{
    if(thingsAreAllDone)
    {
        [timer invalidate];
    }
}
于 2011-07-08T06:56:13.040 に答える