NSTimer
フレームワーク:OS X 10.0 以降の Foundation。関連項目
概観
タイマーオブジェクトや、より簡単に、タイマーを作成するために、NSTimer クラスを使用して下さい。一定の時間間隔が経過し起動し、ターゲットオブジェクトに指定されたメッセージを送信するまでタイマーは待機します。たとえば、特定の時間間隔の後に自分自身を更新するため知らせるのに、ウィンドウにメッセージを送信するため NSTimer オブジェクトを作成できます。
タイマーは、実行ループと連動して動作します。効果的にタイマーを使用するには、実行ループがどのように操作するかを知るべきです。NSRunLoop と スレッドプログラミングガイド を、参照してください。実際、実行ループがそのタイマーに強い参照を維持するので、実行ループにそれを追加した後、タイマーに独自の強い参照を維持する必要はない事に注意してください。
タイマーは、リアルタイムのメカニズムはありません。それは、タイマーが追加された実行ループモードの一つのモードが実行中にのみ起動し、タイマーの起動時間が経過したかどうかを確認することができます。典型的な実行ループが管理するさまざまな入力ソースがあるため、タイマーの時間間隔の有効分解能は 50 から 100 ミリ秒のオーダーに制限されています。タイマーの起動時間が長いコールアウト中または実行ループが、タイマーをモニターしていないモードにある間に発生した場合、次回は、実行ループが、タイマーをチェックするまで、タイマーは起動しません。したがって、タイマーが潜在的に起動する実際の時刻は、スケジュールされた起動時間後のかなりの期間でありえます。また、タイマーの耐性 を参照してください。
NSTimer は、Core Foundation の相手、CFRunLoopTimerRef と"通話無料で繋がって" います。通話無料で繋がる詳細については、通話無料で繋がる" を参照してください。
繰り返す対繰り返さないタイマー
タイマーが作成時に繰り返しか繰り返して出ないかどうかを指定します。繰り返しでないタイマーは一旦起動し、その後自分自身を無効にし、それによって再び起動する事からタイマーを防止します。これとは対照的に、繰り返すタイマーは起動し、その後同じ実行ループに自分自身を再スケジュールします。
繰り返すタイマーは、実際の起動時間とは対照的に、スケジュールされた起動時間に基づいて、それ自身をスケジュールします。例えば、タイマーが特定の時間とその後 5 秒ごとに起動するようにスケジュールされている場合、スケジュールされた起動時間は、常に実際の起動時間が遅れる場合でも、元の 5 秒の時間間隔に落ちます。起動時間が、これまでのところ、それがスケジュールされた起動時間の一つ以上を通過して遅れた場合、タイマーは、その期間に 1 回のみ起動されます。タイマーは、その後、将来的に次のスケジュール起動時間のために、起動後、再スケジュールされます。
タイマーの耐性
iOS 7 以降と OS X v10.9 以降では、タイマーの耐性(tolerance) を指定できます。タイマーの起動が増加した電力の節約と応答性を最適化するためシステムの能力を向上させたときに、システムを柔軟性にします。タイマーは、そのスケジュールされた起動日とスケジュールされた起動日プラス耐性の間の任意の時点で起動することができます。タイマーは、スケジュールされた起動日より前には起動しません。タイマーを繰り返すためには、次の起動日付がドリフトを回避するために、個々の起動時間を適用された耐性には関係なく、元の起動日から計算されます。デフォルト値はゼロで、追加の耐性が適用されないことを意味します。システムは tolerance (耐性) プロパティの値にかかわらず、一定のタイマーに対する少量の耐性を適用する権利を有します。
タイマーのユーザーとして、タイマーの適切な耐性があるかもしれない最高のアイデアを持っているでしょう。一般に大雑把に言って、しかし、繰り返しタイマーの、間隔の少なくとも 10 %に耐性を設定することです。少量の耐性でも、アプリケーションの電力使用量に大きなプラスの影響を与えることになります。システムは耐性の最大値を出すかも知れません。
実行ループでタイマーをスケジュール
タイマーオブジェクトは、一度に一つだけ実行ループに登録することができますが、その実行ループ内の複数の実行ループモードに追加できます。タイマーを作成するためには 3 つの方法があります。
- scheduledTimerWithTimeInterval:invocation:repeats: か scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: クラスメソッドを使用して、タイマーを作成し、現在の実行ループにデフォルトのモードでスケジュールします。
- timerWithTimeInterval:invocation:repeats: か timerWithTimeInterval:target:selector:userInfo:repeats: クラスメソッドを使用して実行ループにそれをスケジュールせずにタイマーオブジェクトを作成します。(それを作成した後、対応する NSRunLoop オブジェクトの addTimer:forMode: を呼び出して手動で実行ループにタイマーを追加しなければなりません。)
- initWithFireDate:interval:target:selector:userInfo:repeats: メソッドを使用して、タイマーを割り当て、それを初期化します。(それを作成した後、対応する NSRunLoop オブジェクトの addTimer:forMode: を呼び出して手動で実行ループにタイマーを追加しなければなりません。)
実行ループ上で一旦スケジュールすると、タイマーは指定した間隔でそれが無効化されるまで起動します。繰り返さないタイマーは起動直後に自分自身を無効にします。しかし、繰り返しタイマーの場合、その invalidate メソッドを呼び出して、タイマーオブジェクトを自分自身で無効にしなければなりません。このメソッドを呼び出すと、現在の実行ループからタイマの削除を要求します。結果として、常に、タイマーがインストールされた同じスレッドから invalidate メソッドを呼び出す必要があります。タイマーを無効にすると、すぐにそれを不可能にし、もはや実行ループに影響を与えません。実行ループは、その後、タイマー(とタイマーに持っていた強い参照) を削除し、ちょうど invalidate メソッドが戻る前またはその後のある時点のどちらで、削除します。いったん無効にされると、タイマーオブジェクトは再利用できません。
繰り返しタイマーが起動した後、指定した tolerance 内で、最後にスケジュールされた起動日の後のタイマー間隔の整数倍である最も近い将来の日付のために次の起動をスケジュールします。時間が、セレクタや呼び出しを実行するために取られた場合は指定した間隔よりも長く、タイマーは次の起動をスケジュールするのみです。つまり、タイマーは、指定されたセレクターや呼び出しに発生したであろう全ての失敗した起動を補正しようとしません。
サブクラス化の注意事項
NSTimer をサブクラス化するべきではありません。
タスク
タイマーの作成
+ scheduledTimerWithTimeInterval:invocation:repeats:
デフォルトモードで現在の実行ループ上に新しい NSTimer オブジェクトとスケジュールを作成し、返します。
宣言
<< SWIFT >>
class func scheduledTimerWithTimeInterval(_ ti: NSTimeInterval, invocation invocation: NSInvocation, repeats yesOrNo: Bool) -> NSTimer << OBJECTIVE-C >> + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)repeats
パラメーター
ti | タイマーの起動間の秒数。ti が 0.0 以下である場合、このメソッドは、代わりに 0.1 ミリセカンドの負でない値を選択します。 |
invocation | タイマーが起動する時に使用する呼び出し(invocation)。タイマーが無効化されるまで、invocation オブジェクトは、その引数への強い参照を保持します。 |
repeats | YES の場合、タイマーは無効化されるまで、自分自身を繰り返し再スケジュールします。NO の場合、起動後にタイマーは無効になります。 |
戻り値
指定されたパラメータに基づいて構成された、新しい NSTimer オブジェクト。
宣言
ti 秒が経過した後、タイマーは起動し、invocation を呼び出します。
利用可能
OS X 10.0 以降で利用できます。
+ scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
デフォルトモードで現在の実行ループに新しい NSTimer オブジェクトとスケジュールを作成し、返します。
宣言
<< SWIFT >>
class func scheduledTimerWithTimeInterval(_ ti: NSTimeInterval, target aTarget: AnyObject, selector aSelector: Selector, userInfo userInfo: AnyObject?, repeats yesOrNo: Bool) -> NSTimer << OBJECTIVE-C >> + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats
パラメーター
ti | タイマーの起動の間の秒数。ti が 0.0 以下である場合、このメソッドは、代わりに 0.1 ミリセカンドの負でない値を選択します。 |
target | タイマーが起動した時 aSelector で指定されたメッセージを送信すべきオブジェクト。タイマーはそれ(タイマー) が無効化されるまで、target への強い参照を保持します。 |
aSelector | タイマーが起動した時、target に送信するべきメッセージ。 セレクタは、以下のシグネチャを持つ必要があります:timerFireMethod:(メソッドが、引数を取ることを示すためにコロンを含む)。タイマーは、引数として自分自身を渡し、メソッドは以下のパターンを採用するだろう。 - (void)timerFireMethod:(NSTimer *)timer |
userInfo | タイマー用のユーザ情報。それ(タイマー) が無効化されるまでタイマーは、このオブジェクトへの強い参照を維持します。このパラメータは nil であってもよいです。 |
repeats | YES の場合、タイマーは無効化されるまで、自分自身を繰り返し再スケジュールします。NO の場合起動後に、タイマーは無効になります。 |
戻り値
指定されたパラメータに基づいて構成された、新しい NSTimer オブジェクト。
議論
ti 秒が経過した後、タイマーは起動し、メッセージを aSelector から target に送信します。
利用可能
OS X 10.0 以降で利用できます。
+ timerWithTimeInterval:invocation:repeats:
指定された呼び出しオブジェクトで初期化された新しい NSTimer オブジェクトを作成し、返します。
宣言
<< SWIFT >>
init(timeInterval ti: NSTimeInterval, invocation invocation: NSInvocation, repeats yesOrNo: Bool) << OBJECTIVE-C >> + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)repeats
パラメーター
ti | タイマーの起動の間の秒数。ti が 0.0 以下である場合、このメソッドは、代わりに 0.1 ミリセカンドの負でない値を選択します。 |
invocation | タイマーが起動した時に使用するべき呼び出し。タイマーは、呼び出しオブジェクトを指示して、その引数への強い参照を維持します。 |
repeats | YES の場合、タイマーは無効化されるまで、自分自身を繰り返し再スケジュールします。NO の場合、起動後にタイマーは無効になります。 |
戻り値
指定されたパラメータに基づいて構成された、新しい NSTimer オブジェクト。
議論
addTimer:forMode: を使用して、実行ループに新しいタイマーを追加しなければなりません。その後、ti が経過した後に続いて、タイマーは起動し、invocation を呼び出します。(タイマーが繰り返すように構成されている場合は、その後に実行ループにタイマーを再度追加する必要はありません。)
利用可能
OS X 10.0 以降で利用できます。
+ timerWithTimeInterval:target:selector:userInfo:repeats:
指定したオブジェクトとセレクタで初期化された新しい NSTimer オブジェクトを作成し、返します。
宣言
<< SWIFT >>
init(timeInterval ti: NSTimeInterval, target aTarget: AnyObject, selector aSelector: Selector, userInfo userInfo: AnyObject?, repeats yesOrNo: Bool) << OBJECTIVE-C >> + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats
パラメーター
ti | タイマーの起動の間の秒数。ti が 0.0 以下である場合、このメソッドは、代わりに 0.1 ミリセカンドの負でない値を選択します。 |
target | タイマーが起動する時、aSelector で指定されたメッセージを送信すべき、オブジェクト。それ(タイマー) が無効化されるまでのタイマーは、このオブジェクトへの強い参照を維持します。 |
aSelector | タイマーが起動した時、target に送信するべきメッセージ。 セレクタは、以下のシグネチャを持つ必要があります:timerFireMethod:(メソッドが、引数を取ることを示すためにコロンを含む)。タイマーは、引数として自分自身を渡し、メソッドは以下のパターンを採用するだろう。 - (void)timerFireMethod:(NSTimer *)timer |
userInfo | タイマー用のカスタムユーザー情報。 それ(タイマー) が無効化されるまでタイマーは、このオブジェクトへの強い参照を保持します。このパラメータは nil であってもよいです。 |
repeats | YES の場合、タイマーは無効化されるまで、自分自身を繰り返し再スケジュールします。NO の場合、起動後にタイマーは無効になります。 |
戻り値
指定されたパラメータに基づいて構成された新しい NSTimer オブジェクト。
議論
addTimer:forMode: を使用して、実行ループに新しいタイマーを追加しなければなりません。その後、ti 秒が経過した後、メッセージを aSelector から target に送信します。(タイマーが繰り返すように構成されている場合、その後実行ループにタイマーを再度追加する必要はありません。)
利用可能
OS X 10.0 以降で利用できます。
- initWithFireDate:interval:target:selector:userInfo:repeats: 指定イニシャライザ
指定されたオブジェクトとセレクタを使用して、新しい NSTimer オブジェクトを初期化します。
宣言
<< SWIFT >>
init(fireDate date: NSDate, interval ti: NSTimeInterval, target t: AnyObject, selector s: Selector, userInfo ui: AnyObject?, repeats rep: Bool) << OBJECTIVE-C >> - (instancetype)initWithFireDate:(NSDate *)date interval:(NSTimeInterval)ti target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats
パラメーター
date | タイマーが最初に起動する時刻。 |
ti | 繰り返しタイマーの場合、このパラメータは、タイマーの起動間隔の秒数を含んでいます。ti が 0.0 以下である場合、このメソッドは、代わりに 0.1 ミリセカンドの負でない値を選択します。 |
target | タイマーが起動する時に、aSelector で指定されたメッセージを送信すべきオブジェクト。それ(タイマー) が無効化されるまで、タイマーはこのオブジェクトへの強い参照を維持します。 |
aSelector | タイマーが起動する時、target に送信すべきメッセージ。 セレクタは、次のシグネチャを持つ必要があります:timerFireMethod: (メソッドが、引数を取ることを示すためにコロンを含む)。タイマーは引数として自分自身を渡し、このようにメソッドは以下のパターンを採用するだろう。 - (void)timerFireMethod:(NSTimer *)timer |
userInfo | タイマー用のカスタムユーザー情報。それ(タイマー)が無効化されるまで、タイマーは、このオブジェクトへの強い参照を維持します。このパラメータは nil であってもよいです。 |
repeats | YES の場合、タイマーは無効化されるまで、自分自身を繰り返し再スケジュールします。NO の場合、起動後に、タイマーは無効になります。 |
戻り値
受信者は、実行ループに加えられたとき、などに初期化し、それは date に起動し、その後、repeats が YES である場合、その後のすべての ti で。
議論
addTimer:forMode: を使用して、実行ループに新しいタイマーを追加しなければなりません。起動時には、タイマーは aSelector から target にメッセージを送信します。(タイマーが繰り返すように構成されている場合は、その後に実行ループにタイマーを再度追加する必要はありません。)
利用可能
OS X 10.2 以降で利用できます。
タイマーの起動
- fire
受信者のメッセージがそのターゲットに送信されます。
宣言
<< SWIFT >>
func fire() << OBJECTIVE-C >> - (void)fire
議論
その定期的な起動スケジュールを中断することなく、繰り返しタイマーを起動するために、このメソッドを使用できます。タイマーが繰り返しでない場合、スケジュールされた起動日が到来していない場合でも、起動後に自動的に無効にされます。
利用可能
OS X 10.0 以降で利用できます。
以下も見よ
– invalidateタイマーの停止
– invalidate
二度と起動する事から受信者を停止し、その実行ループから削除を要求します。
宣言
<< SWIFT >>
func invalidate() << OBJECTIVE-C >> - (void)invalidate
議論
このメソッドは、NSRunLoop オブジェクトからタイマーを削除する唯一の方法です。NSRunLoop オブジェクトは、ちょうど invalidate メソッドが戻る前か、または少し後の時点のいずれかで、タイマーへの強い参照を削除します。
それがターゲットとユーザ情報オブジェクトで構成されていた場合、受信者は同様にそれらのオブジェクトへの強い参照を削除します。
特別な考慮事項
タイマーがインストールされているスレッドから、このメッセージを送信しなければなりません。別のスレッドからこのメッセージを送信すると、タイマーに関連した入力ソースはその実行ループから削除されないことがあり、正しく終了する事からスレッドを防ぐことができます。
利用可能
OS X 10.0 以降で利用できます。
以下も見よ
– fireタイマーに関する情報
valid プロパティ
受信者が現在有効であるかどうかを示すブール値。(読み取り専用)
宣言
<< SWIFT >>
var valid: Bool { get } << OBJECTIVE-C >> @property(readonly, getter=isValid) BOOL valid
議論
受信者がまだ起動することができる場合 YES、またはタイマーが無効にされている場合で、もはや起動できない場合 NO。
利用可能
OS X 10.0 以降で利用できます。
fireDate プロパティ
タイマーが起動するときの日付。
宣言
<< SWIFT >>
@NSCopying var fireDate: NSDate << OBJECTIVE-C >> @property(copy) NSDate *fireDate
議論
タイマーがもはや有効でない場合、タイマーが起動した最後の日付。
繰り返しタイマーの起動時間を調整するためにこのプロパティを設定できます。タイマーの次の起動時間をリセットするのは、比較的高価な操作ですが、いくつかの状況では、より効率的です。たとえば、あなたが将来的にアクションを複数回繰り返したい状況でそれを使用できますが、不規則な時間間隔です。単一のタイマーの起動時間を調整するのは、複数のタイマーオブジェクトを作成し、実行ループ上の各々一つをスケジュールし、それらを破壊するよりも高価ではない事に落ち込みます。
既に無効にされている、繰り返しでない、既に起動しているタイマーを含むタイマーの起動の日付を変更するべきではありません。まだ起動していない繰り返しでないタイマーの起動の日付を潜在的に変更してしまうことがありますが、潜在的な競合状態を避けるために、タイマーが取り付けられたスレッドから行う必要があります。
タイマーが有効であることを確認するために、isValid メソッドを使用して下さい。
(訳注) 何度見てもメソッドの前に書いてあるのは isValid である。しかしてリンク先は valid です。典型的な typo であろう。
利用可能
OS X 10.0 以降で利用できます。
timeInterval プロパティ
タイマーの時間間隔。(読み取り専用)
宣言
<< SWIFT >>
var timeInterval: NSTimeInterval { get } << OBJECTIVE-C >> @property(readonly) NSTimeInterval timeInterval
議論
受信者が繰り返しでないタイマーの場合、時間間隔が設定された場合でも、0 を返します。
利用可能
OS X 10.0 以降で利用できます。
userInfo プロパティ
受信者の userInfo オブジェクト。(読み取り専用)
宣言
<< SWIFT >>
var userInfo: AnyObject? { get } << OBJECTIVE-C >> @property(readonly, retain) id userInfo
議論
タイマーが無効化された後、このプロパティにアクセスしないでください。タイマーが有効かどうかをテストするには isValid を使用してください。
利用可能
OS X 10.0 以降で利用できます。
以下も見よ
+ scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:+ timerWithTimeInterval:target:selector:userInfo:repeats:
– invalidate
起動の耐性
tolerance プロパティ
タイマーが起動できる、スケジュールされた起動の日付後の時間の量。
宣言
<< SWIFT >>
var tolerance: NSTimeInterval << OBJECTIVE-C >> @property NSTimeInterval tolerance
議論
デフォルト値はゼロであり、追加の耐性が適用されないことを意味します。
タイマーの耐性を設定すると、スケジュールされた起動日より以降に起動することができます。タイマーの起動が増加した電力の節約と応答性を最適化するためシステムの能力を増大させたときにおけるシステムの柔軟性を可能にします。
タイマーは、そのスケジュールされた起動日とスケジュールされた起動日プラス耐性の間の任意の時点で起動できます。タイマーは、スケジュールされた日より前に起動しません。繰り返しのタイマーの場合、次の起動日はドリフトを回避するために、個々の起動の時点で適用される耐性に関係なく、元の起動日から計算されます。システムは、このプロパティの値にかかわらず一定のタイマーに対する少量の耐性を適用する権利があります。
利用可能
OS X 10.9 以降で利用できます。
次の章