PerformSelector no funciona

El método MyThreadRun se invoca desde MyMethod de esta manera

NSArray* args = [NSArray arrayWithObjects:arg1, target, NSStringFromSelector(mySelector), nil];
NSThread* mythread= [[[NSThread alloc] initWithTarget:self selector: @selector(MyThreadRun:) object:args] autorelease];
[MyThreadRun start];

Al final de MyThreadRun, trato de invocar una función en la clase que ha llamado MyMethod para iniciar el hilo para empezar, así:

NSObject* callbackTarget = [args objectAtIndex:1];
NSString* selector = [args objectAtIndex:2];
[callbackTarget performSelector:NSSelectorFromString(selector) withObject:calculationResult afterDelay:0];

Tengo un punto de interrupción en el método al que apunta el selector, y nunca se golpea.

Si codifico el nombre del método, así

[callbackTarget updateWithResult:calculationResult] 

funciona bien.

¿Qué necesito saber sobre performSelector?

preguntado el 28 de agosto de 11 a las 05:08

3 Respuestas

El contexto donde performSelector:withObject:afterDelay: está siendo invocado es el culpable. Esto es lo que está pasando.

Algunos miembros de la performSelector... familia, como esta, no realice el selector de inmediato; ponen en cola una invocación en el ciclo de ejecución actual, de modo que suceda después de que su fn regrese, la siguiente ronda del ciclo de ejecución. Según Apple: "Especificar un retraso de 0 no necesariamente hace que el selector se ejecute inmediatamente. El selector todavía está en cola en el ciclo de ejecución del hilo y se realiza lo antes posible".

Normalmente esto está bien y es de esperar. Pero su código lo está llamando en un hilo que inició manualmente ... y esos hilos no mantienen su ciclo de ejecución repetidamente como lo hace el hilo principal. Invocan el selector especificado en la creación una vez y salen. Entonces: su código pone en cola una invocación de su selector de devolución de llamada, pero luego el hilo sale; y su ciclo de ejecución se desecha sin siquiera ejecutarse ... por lo que su invocación en cola nunca ocurre.

Lo que probablemente necesites es performSelectorOnMainThread:withObject:waitUntilDone:, ya que es posible que desee que la devolución de llamada ocurra en el hilo que invocó el MyMethod método en primer lugar, que es presumiblemente el hilo principal.

De manera más general, el enhebrado es algo muy complicado. Recomiendo encarecidamente echar un vistazo NSOperationQueue, NSBlockOperationy técnicas relacionadas, pueden eliminar una gran parte del dolor.

Respondido 28 ago 11, 09:08

Is

NSString* selector = [args objectAtIndex:2];

igual a updateWithResult or updateWithResult:?

Son dos métodos diferentes. Quieres el que tiene los dos puntos.

Respondido 28 ago 11, 09:08

el depurador muestra que termina con dos puntos. Ese valor de cadena se codificó con NSStringFromSelector de todos modos, tengo fe en que la cadena se forma correctamente. - Haoest

Elimina "afterDelay: 0" y tu código funciona. También "[MyThreadRun start]" debería ser "[mythread start]".

Respondido 28 ago 11, 09:08

muy buena observación con el [inicio de la lectura del mito], pero tienes razón, afterDelay fue el problema. Mi teoría es que el parámetro afterDelay pone ese método en una cola, que desaparece cuando termina ese hilo. Incluso trato de poner while (1); al final del método solo para mantener vivo el hilo, pero eso tampoco funcionó. Eliminar afterDelay funcionó. Gracias. Y gracias al intellisense de xcode, perdí unas 3 horas rascándome la cabeza. - Haoest

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.