Estoy tratando de cerrar un NSPanel después de un par de segundos de retraso, pero no puedo hacer que mi NSTimer comience. Se disparará si invoco explícitamente el método de fuego en él, pero nunca irá solo. Aquí está mi código:NSTimer nunca comienza
- (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];
}
Tengo algunos hilos en mi código como tal. Supongo que esto es lo que está estropeando mi temporizador.
-(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];
}
¿Qué se llama desde otro método por: [self performSelectorInBackground:@selector(incomingTextUpdateThread:) withObject:[NSThread currentThread]];
Hmm ... no veo nada mal, pero ¿por qué pasa el actualThread como el parámetro withObject:? Parece que no lo utilizas en ese método, ¿por qué no solo pasas nulo? – jakev
Una sospecha que tengo (solo una sospecha, ya que no puedo ver qué llamadas startRemoveProgressTimer :) scheduledTimerWithTimeInterval agrega el temporizador al ciclo de ejecución del subproceso actual, no al del subproceso principal. Si está creando su temporizador en una secuencia de fondo que nunca usa su ciclo de ejecución, si solo se sienta y gira en un rato (1) leyendo un bucle desde un descriptor de archivo, digamos, el bucle de ejecución nunca tiene la oportunidad de tratar con cualquier temporizador en cola. Intente agregarlo explícitamente al bucle de ejecución del subproceso principal y vea qué sucede. – rgeorge
¿Haría una diferencia si le dijera que startRemoveProgressTimer: está vinculado a una NSNotification? En cuanto a por qué estoy pasando el hilo actual, no estoy seguro. Estoy tratando de adaptar el código de otra persona a mi aplicación. El código original está aquí: http://arduino.cc/playground/Interfacing/Cocoa pero tuve que hacer algunas modificaciones para compilarlo en (Snow) Leopard, y puse algo de mi propia lógica. –