web-dev-qa-db-ja.com

NSTimerを使用してObjective-Cでx秒ごとにメソッドを呼び出す方法は?

Objective-C、Xcode 4.5.1を使用し、iPhone用のアプリで作業しています。

X秒ごとに一連の計算を行うために別のメソッドBを呼び出すメソッドAがあります。方法Aでは、オーディオファイルの再生を開始します。方法Bは、オーディオファイルの期間中、x秒ごとにオーディオを監視します。

NSTimerが潜在的な解決策であることを発見しましたが、それを動作させる/理解するのに苦労しています。

メソッドBをx秒ごとに呼び出して計算を実行したいだけですが、NSTimerでは、何を伝えるべきかわからないいくつかの項目を提供する必要があります。

[NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval) 
target:(id) select:(SEL) userInfo:(id) repeats:(BOOL)];

NSTimeIntervalNSTimerを動作させたい間隔を提供することは私の理解です。しかし、方法Bを実行するように指示するにはどうすればよいですか?

サンプルコードを見てきましたが、現在は 'select: '。しかし、「target: '?なぜターゲットが必要なのですか? 「self」と入力しようとしましたが、Xcodeに次のように表示されます。

宣言されていない識別子「self」の使用

[NSTimer scheduledTimerWithTimeInterval:0.1 target:self 
select:@selector(targetMethod:myVolumeMonitor()) userInfo:nil repeats:YES];

したがって、「self」はオブジェクトへのポインタであるはずですが、どこを指したいのでしょうか。

以下は私のコードの単純化です:

MethodA()
{
//Start playing an audio file.

//NSTimer calling Method B, as long the audio file is playing, every x seconds.
}

MethodB()
{
//Do calculations.
}

誰かが私にいくつかの答えを提供してくれたり、正しい方向に私を向けることができたら感謝しています! (:

23
RoelfMik

ターゲットは、selectで指定されたメッセージの受信者です。 Objective-Cでは、関数は呼び出されません。むしろオブジェクトに送信されるメッセージがあります。オブジェクトは内部的にシンボルテーブルを参照し、どのメソッドが呼び出されているかを判断します。それはセレクターです。セレクタは@selector(MethodB)です。 (ところで:メソッド名は小文字で開始する必要があります。ここでは「methodB」の方が適切です。)これにより、メッセージの送信先のオブジェクトをどのように判断するのでしょうか?それが目標です。あなたの場合、それは単にselfです。

BTW:この場合、セレクターはvoidを返し、NSTimerオブジェクト自体のIDであるidを受け入れることが期待されます。これは、プログラムロジックに応じたいくつかの条件に基づいてタイマーの起動を停止する場合に便利です。最も重要なのは、セレクターがmethodB:ではなくmethodB

- (void) methodA
{
//Start playing an audio file.

//NSTimer calling Method B, as long the audio file is playing, every 5 seconds.
[NSTimer scheduledTimerWithTimeInterval:5.0f 
target:self selector:@selector(methodB:) userInfo:nil repeats:YES];
}

- (void) methodB:(NSTimer *)timer
{
//Do calculations.
}
40
Hermann Klecker

これを試して

 NSTimer *aTimer = [NSTimer timerWithTimeInterval:(x) target:self selector:@selector(timerFired:) userInfo:nil repeats:YES];

    NSRunLoop *runner = [NSRunLoop currentRunLoop];
    [runner addTimer:aTimer forMode: NSDefaultRunLoopMode];  
    [popUpImageView release];

- (void)timerFired:(NSTimer*)theTimer 
{
if(condition)
{
  [theTimer isValid]; //recall the NSTimer
   //implement your methods
}
else
{
  [theTimer invalidate]; //stop the NSTimer

}

}
6
NANNAV

さて、あなたは通常のCメソッドを呼び出そうとしていますが、 NSTimer はできません。

ターゲットは、 selector を呼び出すクラスのインスタンスであり、このセレクターは選択されません。ここでのセレクタは、@selector(METHOD_NAME)関数で作成できるSEL型です。

たとえば、これはhandleTimer :を0.1秒ごとに呼び出します(この例では、AppDelegateが使用されます)。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //SNIP, some code to setup the windos.   

    [NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(handleTimer:) userInfo:nil repeats:YES];
    return YES;
}

- (void) handleTimer:(NSTimer *)timer {
    // Hanlde the timed event.
}
5
rckoenes

コードを見て、以下のコードと比較すると

[NSTimer scheduledTimerWithTimeInterval:0.1 target:self
select:@selector(targetMethod:myVolumeMonitor()) userInfo:nil repeats:YES];

selfは、クラスの同じインスタンスでメソッドを呼び出していることを意味します。この例では、メソッドはmyVolumeMonitorです

[NSTimer scheduledTimerWithTimeInterval:0.1 target:self
selector:@selector(MethodB) userInfo:nil repeats:YES];

そして、あなたは行ってもいいです

メソッドは次のようになります

- (void)MethodB:(NSTimer*)timer { 
// do something
}
4
CodeBro