2

この質問は、スタック オーバーフローで死ぬほど聞かれました。たくさんの回答を見てきましたが、どういうわけかまだ問題があります。

とにかく、私は NSTimer を割り当てるので、私のビューではロードされました:

NSTimer *oneSecondTicker = [[NSTimer alloc] init]; 
oneSecondTicker = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateLabelsWithOneSecondTicker) userInfo:nil repeats:YES]; 
self.dateForTimeLabel = [NSDate date];

セレクターであるメソッドは次のとおりです。

-(void) updateLabelsWithOneSecondTicker {
    if(self.dateForTimeLabel != nil)  
    {
        self.lblTime.text = [NSString stringWithFormat:@"%f", fabs([self.dateForTimeLabel timeIntervalSinceNow])];
    }
}

このメソッドは、基本的に毎秒ラベルを更新し、タイマー/ストップウォッチのようなものを提供します。

開始/一時停止ボタンもあり、押すと一時停止します。

[oneSecondTicker invalidate];
oneSecondTicker = nil;

ボタンを押して再度開始する場合の方法は次のとおりです。

NSTimer *oneSecondTicker = [[NSTimer alloc] init];
oneSecondTicker = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateLabelsWithOneSecondTicker) userInfo:nil repeats:YES];    

self.dateForTimeLabel = [NSDate date];

タイマーに保持を呼び出しません。プロパティがなく、合成されません。ただし、インターフェイスで宣言されています。

問題を解決するには、一時停止/開始ボタンを押すたびに、タイマーが無効にならず、時間ラベルがどんどん更新されるようになるため、何らかの理由で複数のタイマーが存在すると思われます。(明らかに、実際のタイマーの機能はこれらのメソッドにはまだありません。これは、私の NSTimer を機能させるための単なるテストです)。

どうすればいいの?

4

2 に答える 2

11

あなたはこれを書きました:

NSTimer *oneSecondTicker = [[NSTimer alloc] init];

その行はローカル変数を作成します。インターフェイスで宣言したプロパティは設定されません。oneSecondTickerその行はタイマーも作成します。次の行で、 で作成したタイマーを指すように再割り当てするとすぐに破棄しますscheduledTimerWithTimeInterval:。これは、ポインタの仕組みを学ぶ必要があることを示す初心者の間違いです。

とにかく、を使用してタイマーを作成していますscheduledTimerWithTimeInterval:...。つまり、タイマーは実行ループで自動的にスケジュールされます。タイマーが実行ループでスケジュールされている場合、実行ループはタイマーを保持します。そのため、(ARC を使用していると仮定して) タイマーへの参照を解放しているにもかかわらず、タイマーは存続します。

インスタンス変数にタイマーを格納する必要があります。Xcode 4.4 以降を使用していると思われるため、プロパティは自動的に合成されています。のようにプロパティを宣言した場合、次のよう@property (nonatomic, strong) NSTimer *oneSecondTickerにタイマーを作成できます。

self.oneSecondTicker = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateLabelsWithOneSecondTicker) userInfo:nil repeats:YES]; 

無効にしたい場合は、次のように言えます。

[self.oneSecondTicker invalidate];
self.oneSecondTicker = nil;
于 2012-08-25T05:59:39.003 に答える
0

タイマー変数を保持していません。

これを削除します:

NSTimer *oneSecondTicker = [[NSTimer alloc] init]; 

タイマーをクラスプロパティに移動します@property (strong)NSTimer *oneSecondTicker;

これを使って:

self.oneSecondTicker = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateLabelsWithOneSecondTicker) userInfo:nil repeats:YES];

タイマーを再起動するときは、self.oneSecondTicker を再度使用してください。

于 2012-08-25T05:59:40.973 に答える