2011-02-06 5 views
9

私はちょっと待ってからNSPanelを閉じようとしていますが、NSTimerを起動することができません。私が明示的にfireメソッドを呼び出すと、それは起動しますが、決してそれ自身では行かないでしょう。私のコードは次のとおりです。NSTimerは決して始まらない

- (void)startRemoveProgressTimer:(NSNotification *)notification { 
    NSLog(@"timer should start"); 
    timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(removeProgress:) userInfo:nil repeats:NO]; 
} 

- (void)removeProgress:(NSTimer *)timer { 
    [progressPanel close]; 
} 

私のコードにはスレッドがあります。私はこれが私のタイマーを台無しにしていると仮定しています。別の方法から呼び出され

-(void)incomingTextUpdateThread:(NSThread*)parentThread { 
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

//mark the thread as running 
readThreadRunning = TRUE; 

const int BUFFER_SIZE = 100; 
char byte_buffer[BUFFER_SIZE]; //buffer for holding incoming data 
int numBytes = 0; //number of bytes read 
NSString *text; //incoming text from the serial port 

[NSThread setThreadPriority:1.0]; 

//this will loop until the serial port closes 
while (TRUE) { 
    //read() blocks until some data is available or the port is closed 
    numBytes = read(serialFileDescriptor, byte_buffer, BUFFER_SIZE); 
    if(numBytes > 0) { 
     //creat a string from the incoming bytes 
     text = [[[NSString alloc] initWithBytes:byte_buffer length:numBytes encoding:[NSString defaultCStringEncoding]] autorelease]; 
     if(!([text rangeOfString:SEND_NEXT_COORDINATE].location == NSNotFound)) { 
      //look for <next> to see if the next data should be sent 
      if(coordinateNum <[coordinatesArray count]) { 
       [self sendNextCoordinate]; //send coordinates 
      } 
      else { 
       [self writeString:FINISH_COORDINATES_TRANSMIT]; //send <end> to mark transmission as complete 
       NSNumber *total = [NSNumber numberWithUnsignedInteger:[coordinatesArray count]]; 
       NSDictionary *userInfo = [NSDictionary dictionaryWithObject:total forKey:@"progress"]; 
       [[NSNotificationCenter defaultCenter] postNotificationName:@"uploadProgressChange" object:self userInfo:userInfo]; //update progress bar to completed 
      } 


     } 

     [self performSelectorOnMainThread:@selector(appendToIncomingText:) withObject:text waitUntilDone:YES]; //write incoming text to NSTextView 
    } else { 
     break; //Stop the thread if there is an error 
    } 
} 

// make sure the serial port is closed 
if (serialFileDescriptor != -1) { 
    close(serialFileDescriptor); 
    serialFileDescriptor = -1; 
} 

// mark that the thread has quit 
readThreadRunning = FALSE; 

// give back the pool 
[pool release]; 
} 

[self performSelectorInBackground:@selector(incomingTextUpdateThread:) withObject:[NSThread currentThread]];

+0

Hmm ...間違っているとは見えませんが、currentThreadをwithObject:パラメータとして渡すのはなぜですか?あなたはその方法でそれを使用しているようには見えません。 – jakev

+7

私は疑いがあります(私はstartRemoveProgressTimer:startsTimerWithTimeIntervalを呼び出すことができないので、疑いがあります)、メインスレッドではなく現在のスレッドの実行ループにタイマーを追加します。実行ループを使用しないバックグラウンドスレッドでタイマーを作成している場合 - ファイル記述子からwhile(1)ループを読み込んでスピンするだけでは、実行ループは決して対処する機会を得ません待ち行列に入れられたタイマー明示的にメインスレッドの実行ループに追加して、何が起こるかを見てください。 – rgeorge

+0

startRemoveProgressTimer:がNSNotificationに結びついていると言えば、違いがありますか?なぜ私が現在のスレッドで渡しているかについては、わかりません。私は他の人のコードを自分のアプリケーションに適応しようとしています。元のコードはhttp://arduino.cc/playground/Interfacing/Cocoaですが、(Snow)Leopardでコンパイルするためにいくつか修正を加えなければならず、自分のロジックをいくつか入れました。 –

答えて

18

あなたはrgeorgeありがとう!!

タイマーを実行ループに手動で追加すると、手動で動作しました!

timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(removeProgress:) userInfo:nil repeats:NO]; 
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; 
+4

特に、それを* main *(メインスレッドの)実行ループに追加します。 'scheduledTimer ...'メソッドは実行ループにタイマを追加しますが、現在の(現在のスレッドの)実行ループに追加します。また、タイマーの作成/スケジューリングによって応答するメインスレッドの実行を行うこともできました。 –

関連する問題