2011-02-06 35 views
9

Tôi chỉ đang cố đóng một NSPanel sau một vài giây trì hoãn, nhưng tôi không thể bắt NSTimer của mình. Nó sẽ cháy nếu tôi gọi một cách rõ ràng phương pháp lửa trên nó, nhưng nó sẽ không bao giờ đi một mình. Đây là mã của tôi:NSTimer không bao giờ bắt đầu

- (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]; 
} 

Tôi có một số luồng trong mã của mình như vậy. Tôi cho rằng đây là những gì gây rối hẹn giờ của tôi lên.

-(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]; 
} 

nào được gọi là từ phương pháp khác bằng cách: [self performSelectorInBackground:@selector(incomingTextUpdateThread:) withObject:[NSThread currentThread]];

+0

Hmm ... không thấy bất cứ điều gì sai, nhưng tại sao bạn chuyển dòng lệnhThông tin này thành tham số withObject:? Bạn dường như không sử dụng nó trong phương pháp đó, tại sao không chỉ vượt qua nil? – jakev

+7

Một nghi ngờ tôi có (chỉ là một nghi ngờ, vì tôi không thể nhìn thấy những gì các cuộc gọi startRemoveProgressTimer :) scheduleTimerWithTimeInterval thêm bộ đếm thời gian cho vòng lặp chạy của thread hiện tại, không phải là chủ đề chính. Nếu bạn đang tạo bộ đếm thời gian trong chuỗi nền không bao giờ sử dụng vòng lặp chạy của nó - nếu chỉ ngồi và quay trong một vòng lặp while (1) từ bộ mô tả tệp, hãy nói - vòng lặp chạy không bao giờ có cơ hội để xử lý bất kỳ bộ hẹn giờ xếp hàng nào. Hãy thử thêm nó một cách rõ ràng vào vòng lặp chạy của chuỗi chính và xem điều gì sẽ xảy ra. – rgeorge

+0

Nó có tạo sự khác biệt nếu tôi nói với bạn rằng startRemoveProgressTimer: được gắn với NSNotification không? Về lý do tại sao tôi đi qua trong chủ đề hiện tại, tôi không chắc chắn. Tôi đang cố gắng điều chỉnh mã của người khác cho ứng dụng của tôi. Các mã ban đầu là ở đây: http://arduino.cc/playground/Interfacing/Cocoa nhưng tôi đã phải thực hiện một số sửa đổi để có được nó để biên dịch trên (Snow) Leopard, và tôi đưa vào một số logic của riêng tôi. –

Trả lời

18

Cảm ơn bạn rgeorge !!

Thêm hẹn giờ vào vòng lặp chạy theo cách thủ công khiến nó hoạt động!

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

Cụ thể, thêm nó vào vòng lặp chạy * chính (chủ đề chính). Các phương thức 'scheduleTimer…' thêm bộ đếm thời gian vào vòng lặp chạy, nhưng chúng thêm nó vào vòng lặp chạy hiện tại (luồng hiện tại). Nó cũng sẽ làm việc để thực hiện một chủ đề chính thực hiện mà bạn trả lời bằng cách tạo/lập lịch hẹn giờ. –

Các vấn đề liên quan