1

アプリのサーバーからsecondsToEnd値を使用して情報を取得し、この情報を受信した後にカウンターを開始します。

私のプロジェクトにはスクロールビューが含まれているので、スクロールによるタイマーのロックを回避するには、次の方法でタイマーをNSRunLoopに追加します。

[[NSRunLoop currentRunLoop] addTimer:timer
                             forMode:NSRunLoopCommonModes];

NSTimerプロパティを作成しました。これは、どのようにオリジナルで、タイマーであり、これは私のstartTimer関数のスニペット全体です。

- (void)startTimer
{
    if (_timer || [_timer isValid]) [_timer invalidate], _timer = nil, [_timer release];

    NSTimer * timer = [[NSTimer alloc] initWithFireDate:[NSDate date]
                                               interval:1.0
                                                 target:self
                                               selector:@selector(timer:)
                                               userInfo:nil
                                                repeats:YES];

    [[NSRunLoop currentRunLoop] addTimer:timer
                                 forMode:NSRunLoopCommonModes];

    [self setTimer:timer];
    [timer release];
}

startメソッドでチェックが無効になる理由は、secondsToEnd値が0に達した後、新しい値を受け取り、startTimerを再度呼び出すためです。

そして私のdeallocメソッドではこれがあります:

if (_timer || [_timer isValid]) [_timer invalidate], _timer = nil, [_timer release];

しかし、それは無効になりませんか?私は何が間違っているのですか?

4

2 に答える 2

3

これらのカンマ区切りのステートメントはどのような順序で実行されますか? invalidate を呼び出したとき、または release を呼び出したときに _timer が nil の場合はどうなりますか?

if (_timer || [_timer isValid]) [_timer invalidate], _timer = nil, [_timer release];

代わりにこれを試してください。_timer が既に nil かどうかを確認する必要はありません。nil の場合、メソッド呼び出しは何もしません。

if ([_timer isValid]) {
    [_timer invalidate];
}
[_timer release];

dealloc メソッドでは、_timer = nil を設定する必要はありません。このメソッドが終了すると、ストレージはなくなります。

于 2011-09-20T11:45:51.290 に答える
1

最初に電話[timer release]してからtimer = nil. dealloc メソッドでも同じです。外部オブジェクトが autorelease プールにある場合、dealloc メソッドはすぐには呼び出されない可能性があります。このような場合、システムが最終的にオブジェクトを削除することを決定したときに呼び出されます。そのため、時間がかかる場合があります (ブレークポイントを設定した場合)。

ところで、コンマ構文を避け、代わりに中括弧内でブロックを使用することをお勧めします。はるかに読みやすくなっています。

于 2011-09-20T11:32:30.737 に答える