2

NSTimerサブスレッドでを起動しようとしています。私のコードは基本的に次のようになります。

-(void) handleTimer:(NSTimer *)theTimer {  
    NSLog(@"timer fired");  
}

-(void) startMyThread {  
    // If I put timer in here, right before I start my new thread, it fires.  
    // [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(handleTimer:) userInfo:nil repeats:NO];  
    [NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];  
}

// This method is called from inside the new thread  
-(void) playNote:(Note *)theNote withTemplate:(NSString *)theTemplate X:(int)x andY:(int)y {
    NSLog(@"before timer");  
    // The timer doesn't fire in here. (But the print statements do.)  
    [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(handleTimer:) userInfo:nil repeats:NO];
    NSLog(@"after timer");  
}

私は本当に(read:need to?)サブスレッドでタイマーを起動したいと思っています。これは、ノートの再生を停止するために使用されるためです(そして、すべてのノートの再生はサブスレッドで行われる必要があります)。

サブスレッドでの実行方法に何かが欠けているに違いありませんNSTimer...
助けてくれてありがとう!

4

4 に答える 4

5

実行ループでスケジュールされていない限り、タイマーは起動しません。また、スレッドを意地悪にスピンアップすることは避けたいと思うでしょう。

runメソッドが実行ループを起動しない限り、タイマーは起動しません。

より良い解決策は、ところで、GCDを使用することかもしれませんdispatch_after()。糸よりも軽いですが、何をする必要があるかによります。ただし、一般的に、キューはアプリに同時実行性を追加するためのより効率的な手段です。


適切なフォーマットのためにコメントからコードを取得する(良い発見):

double delayInSeconds = .2;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    NSLog(@"dispatch popped");
});

1つの追加の注意; グローバル並行キューの1つを使用することを検討してください。メインイベントループがブロックされる可能性がある場合、それらはブロックされません。もちろん、UIを更新する場合は、とにかくMELに戻る必要があります。

于 2012-07-20T06:23:17.600 に答える
3

にを追加する必要がありNSTimerますcurrentRunLoop。メソッドplayNoteは次のようになります。

-(void) playNote:(Note *)theNote withTemplate:(NSString *)theTemplate X:(int)x andY:(int)y
{
    NSLog(@"before timer");  
    // The timer doesn't fire in here. (But the print statements do.)  
    NSTimer myTimer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(handleTimer:) userInfo:nil repeats:NO];
    [[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] run];
    NSLog(@"after timer");  
}

それはそれをする必要があります:)

于 2012-07-20T06:40:01.913 に答える
1

タイマーを現在の、、に追加しrunloopますrun

-(void) handleTimer:(NSTimer *)theTimer {  
    NSLog(@"timer fired");  
}

-(void) startMyThread {  
    // If I put timer in here, right before I start my new thread, it fires.  
    // [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(handleTimer:) userInfo:nil repeats:NO];  
    [NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];  
}

// This method is called from inside the new thread  
-(void) playNote:(Note *)theNote withTemplate:(NSString *)theTemplate X:(int)x andY:(int)y {
    NSLog(@"before timer");  
    // The timer doesn't fire in here. (But the print statements do.)  
    NSTimer *Timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(handleTimer:) userInfo:nil repeats:NO];
    NSLog(@"after timer");  
    [[NSRunLoop currentRunLoop] addTimer:Timer forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] run];
}
于 2012-07-20T06:23:21.947 に答える
0

1つではなく、addTimer:内で試してください![NSRunLoop mainRunLoop]current

于 2016-07-28T11:09:02.833 に答える