NSTimerの使用方法


344

どのように使用しNSTimerますか?誰かが私に段階的な指示をくれますか?


1
私はpravinmagdum.wordpress.com/2010/12/30/how-to-use-nstimerでパラメーターごとの情報を取得しました..参考になるかもしれません

回答:


616

最初に、Cocoa / CFのドキュメントに注意を向けたいと思います(これは常に最初の呼び出しポートとして優れています)。Appleのドキュメントの各リファレンス記事の上部には、「コンパニオンガイド」と呼ばれるセクションがあり、ドキュメント化されているトピック(存在する場合)のガイドがリストされています。たとえば、のNSTimer場合、ドキュメントには2つの関連ガイドが記載されています。

スレッドトピックは関連していますが、ドキュメント化されているクラスに最も直接関連しているわけではありませんが、状況によっては、タイマープログラミングトピックの記事が最も役立つでしょう。タイマープログラミングトピックの記事を見ると、2つのパートに分かれています。

  • タイマー
  • タイマーの使用

この形式の記事では、多くの場合、クラスとその使用目的の概要があり、次に、この場合の「タイマーの使用」セクションにある、その使用方法に関するサンプルコードがあります。「タイマーの作成とスケジューリング」、「タイマーの停止」、「メモリー管理」のセクションがあります。記事から、スケジュールされた非繰り返しタイマーを作成するには、次のようにします。

[NSTimer scheduledTimerWithTimeInterval:2.0
    target:self
    selector:@selector(targetMethod:)
    userInfo:nil
    repeats:NO];

これにより、2.0秒後に起動され、インスタンスへのポインタである1つの引数で呼び出されるタイマーが作成さtargetMethod:れます。selfNSTimer

その後、メソッドをさらに詳しく調べたい場合は、ドキュメントを参照して詳細を確認できますが、コードに関する説明もあります。

繰り返すタイマーを停止する場合(または、タイマーが起動する前に非反復タイマーを停止する場合)、NSTimer作成したインスタンスへのポインターを保持する必要があります。多くの場合、別のメソッドで参照できるように、インスタンス変数にする必要があります。その後invalidateNSTimerインスタンスを呼び出すことができます。

[myTimer invalidate];
myTimer = nil;

nilインスタンス変数をアウトにすることもお勧めです(たとえば、タイマーを無効にするメソッドが複数回呼び出され、インスタンス変数が設定されておらずnilNSTimerインスタンスの割り当てが解除されている場合は、例外がスローされます)。

記事の下部にあるメモリ管理のポイントにも注意してください。

実行ループはタイマーを維持するため、メモリ管理の観点からは、通常、タイマーをスケジュールした後にタイマーへの参照を保持する必要はありません。タイマーはメソッドをセレクターとして指定すると引数として渡されるため、そのメソッド内で適切なときに繰り返しタイマーを無効にすることができます。ただし、多くの場合、タイマーを無効にするオプションが必要になります。タイマーが開始する前でもかまいません。この場合、タイマーへの参照を保持する必要があるので、適切なときにいつでも無効化メッセージを送信できます。。スケジュールされていないタイマー(「スケジュールされていないタイマー」を参照)を作成する場合は、タイマーへの強い参照を維持し(参照カウント環境では保持)、使用前に割り当て解除されないようにする必要があります。


1つの質問、2秒ごとに実行されるコードとして何を入力しますか?
lab12

あなたが電話YESするrepeats:ときにあなたはパスするでしょうscheduledTimerWithTimeInterval:target:selector:userInfo:repeats:。そうする場合は、NSTimerインスタンスへの参照(メソッドによって返される)を保持していることを確認し、上記で詳述したメモリ管理のポイントに従ってください。
Alex Rozanski、

いいえ、2秒ごとに開始されるコードをどこに配置しますか?たとえば、2秒ごとにビープ音を鳴らしたいとします。ビープ音のコードはどこに入れますか?
lab12

targetおよびで指定するメソッド内selector。たとえば、ターゲットがselfでセレクタがのtimerMethod:場合、タイマーが起動したときに呼び出されるメソッドがでtimerMethod:定義されますself。次に、そのメソッドに必要なコードを配置できます。このメソッドは、タイマーが作動するたびに呼び出されます。タイマーが起動したときに呼び出されるメソッド(として渡されるselector:)は、1つの引数(呼び出されたときにNSTimerインスタンスへのポインター)しか取ることができないことに注意してください。
Alex Rozanski、

申し訳ありませんが、「定義されたself」を意味しました
Alex Rozanski 09/09/20

331

タイマーを使用する方法はいくつかあります。

1)スケジュールされたタイマーとセレクターの使用

NSTimer *t = [NSTimer scheduledTimerWithTimeInterval: 2.0
                      target: self
                      selector:@selector(onTick:)
                      userInfo: nil repeats:NO];
  • repeatsをNOに設定すると、タイマーは2秒待機してからセレクターを実行し、その後停止します。
  • 繰り返す場合:はい、タイマーはすぐに開始し、2秒ごとにセレクターの呼び出しを繰り返します。
  • タイマーを停止するには、タイマーの-invalidateメソッドを呼び出します。[t invalidate];

補足として、繰り返しを行わず、指定された間隔の後にセレクターを呼び出すタイマーを使用する代わりに、次のような単純なステートメントを使用できます。

[self performSelector:@selector(onTick:) withObject:nil afterDelay:2.0];

これは、上記のサンプルコードと同じ効果があります。しかし、セレクターをn回ごとに呼び出す場合は、タイマーをrepeats:YESで使用します。

2)セルフスケジュールタイマー

NSDate *d = [NSDate dateWithTimeIntervalSinceNow: 60.0];
NSTimer *t = [[NSTimer alloc] initWithFireDate: d
                              interval: 1
                              target: self
                              selector:@selector(onTick:)
                              userInfo:nil repeats:YES];

NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer:t forMode: NSDefaultRunLoopMode];
[t release];
  • これにより、ユーザーが指定したカスタム日付(この場合は1分後)に開始するタイマーが作成され、1秒ごとに繰り返されます

3)スケジュールされていないタイマーと呼び出しの使用

NSMethodSignature *sgn = [self methodSignatureForSelector:@selector(onTick:)];
NSInvocation *inv = [NSInvocation invocationWithMethodSignature: sgn];
[inv setTarget: self];
[inv setSelector:@selector(onTick:)];

NSTimer *t = [NSTimer timerWithTimeInterval: 1.0
                      invocation:inv 
                      repeats:YES];

その後、必要に応じて次のように手動でタイマーを開始します。

NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer: t forMode: NSDefaultRunLoopMode];



注として、onTick:メソッドは次のようになります。

-(void)onTick:(NSTimer *)timer {
   //do smth
}

わかりましたが、アプリの透明度を低くしたいので、NSTimerでそれを適用する方法がわかりません
lab12

24
ねえ、今日はこれらの人々..最初からそれを指定しなかったので私から投票して、無駄に書いてみましょう!
2009

28
あなたは無駄に書いていない。これは良い情報です!
willc2

方法2の「セルフタイマー」では、必要なときにタイマーを停止するにはどうすればよいですか。
サティヤム

1
@Satyamsvv、別のメソッドを呼び出すと、タイマーを停止できます。たとえば、[timer invalidate]; タイマー= nil;
Kimpoy

59

このようなもの:

NSTimer *timer;

    timer = [NSTimer scheduledTimerWithTimeInterval: 0.5
                     target: self
                     selector: @selector(handleTimer:)
                     userInfo: nil
                     repeats: YES];

14
まだ順調です... 2014年も!
Muruganandham K 2014

5
#import "MyViewController.h"

@interface MyViewController ()

@property (strong, nonatomic) NSTimer *timer;

@end

@implementation MyViewController

double timerInterval = 1.0f;

- (NSTimer *) timer {
    if (!_timer) {
        _timer = [NSTimer timerWithTimeInterval:timerInterval target:self selector:@selector(onTick:) userInfo:nil repeats:YES];
    }
    return _timer;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}

-(void)onTick:(NSTimer*)timer
{
    NSLog(@"Tick...");
}

@end

どういうわけかそれは保持サイクルを作成するので、MyViewController決して解放されません。
Darrarski、2015

5
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(timerCalled) userInfo:nil repeats:NO];

-(void)timerCalled
{
     NSLog(@"Timer Called");
     // Your Code
}

どこに書いたの?
Mohit 2014

1
この回答@JigneshBだけの背景には使用しないでNSTimerを使用する方法にについてです
Mohit

私はバックグラウンドメソッドで書き込みました--(void)applicationDidEnterBackground:(UIApplication *)application {}
Jignesh B

リピートモードでYES
Jignesh B '09

Appleのドキュメントは、コールバックメソッドの署名について非常に具体的です。あなたのものは間違っています。
ニコライルーエ、2015

2

答えには、次の時間にある特定の時間タイマーがありません:

NSCalendarUnit allUnits = NSCalendarUnitYear   | NSCalendarUnitMonth |
                          NSCalendarUnitDay    | NSCalendarUnitHour  |
                          NSCalendarUnitMinute | NSCalendarUnitSecond;

NSCalendar *calendar = [[ NSCalendar alloc]  
                          initWithCalendarIdentifier:NSGregorianCalendar];

NSDateComponents *weekdayComponents = [calendar components: allUnits 
                                                  fromDate: [ NSDate date ] ];

[ weekdayComponents setHour: weekdayComponents.hour + 1 ];
[ weekdayComponents setMinute: 0 ];
[ weekdayComponents setSecond: 0 ];

NSDate *nextTime = [ calendar dateFromComponents: weekdayComponents ];

refreshTimer = [[ NSTimer alloc ] initWithFireDate: nextTime
                                          interval: 0.0
                                            target: self
                                          selector: @selector( doRefresh )
                                          userInfo: nil repeats: NO ];

[[NSRunLoop currentRunLoop] addTimer: refreshTimer forMode: NSDefaultRunLoopMode];

もちろん、「doRefresh」をクラスの必要なメソッドに置き換えてください

効率を上げるために、カレンダーオブジェクトを一度作成し、allUnitsを静的にしてみてください。

1時間のコンポーネントを追加しても問題なく動作し、午前0時のテストは必要ありません(リンク

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.