2010-03-28 6 views
12

Estoy teniendo algunos problemas para pasar un número como argumento de un método:Int o NSInteger como objeto para el argumento de método. Objective-C

- (void)meth2:(int)next_int; 

Y llamar a ese método necesito esto:

int next_int = 1; 
[self performSelectorOnMainThread:@selector(meth2:) withObject:next_int waitUntilDone:NO]; 
//update next_int and call meth2 again 

en este punto, lo entiendo un "puntero de entero sin un lanzamiento" error y pasaría lo mismo con un NSInteger. Un NSNumber no es útil porque es inmutable y necesito cambiar el valor constantemente. ¿Alguna idea de cómo puedo hacer esto?

Gracias.

Respuesta

22

Si usted está tratando de llamar al método , se puede utilizar la sintaxis estándar:

[self meth2:next_int]; 

Si realmente necesita usar el performSelectorOnMainThread: puede envolver el número en un NSNumber para la llamada. Usted dice que no puede hacer esto porque es necesario para cambiar el número, pero se puede simplemente sacar un int y cambiar eso:

[self performSelectorOnMainThread:@selector(meth2:) withObject:[NSNumber numberWithInt:next_int] waitUntilDone:NO]; 
// ... later ... 
- (void)meth2:(NSNumber *)number { 
    int myInt = [number intValue]; 
    // do stuff with myInt 
} 

Pero tal vez usted quiere decir que usted desea obtener el valor del número como una salida de su llamada al meth2. Si eso es lo que quiere decir, entonces usted podría pasar en un puntero doble para que pueda recibir un nuevo objeto de nuevo:

- (void)meth2:(NSNumber **)number { 
    int myInt = [*number intValue]; 
    // do stuff with myInt 
    *number = [NSNumber numberWithInt:myInt]; 
} 
// The caller can now operate like this: 
NSNumber *number = [NSNumber numberWithInt:next_int]; 
[self performSelectorOnMainThread:@selector(meth2:) withObject:&number waitUntilDone:YES]; 
int returnInt = [*number intValue]; 

Por supuesto, eso no es realmente seguro para subprocesos, por lo que si usted está haciendo cosas con múltiples hilos , Aconsejaría usar la palabra clave @synchronized para acceder a variables accedidas por subprocesos múltiples o configurar propiedades atómicas (es decir, propiedades no declaradas como nonatomic).

Además, la metanfetamina es mala para ti. jaja

+0

Hola Tyler, no estoy seguro acerca de la palabra clave @synchronized, voy a leer sobre, pero desde este la variable entera se usa como un 'resultado' del hilo, no hay necesidad de preocuparse por la concurrencia y esas cosas. El ..withObject: [NSNumber numberWithInt: next_int] .. funciona muy bien, el (NSNumber **) me da una advertencia de tipo de puntero incompatible. Lo tendré en cuenta acerca de la metanfetamina ... ¡gracias! – sergiobuj

2

No puede usar next_int como withObject: porque no es un objeto.

Cambiar la llamada a:

[self performSelectorOnMainThread:@selector(meth2:) 
     withObject:[NSNumber numberWithInt:next_int] waitUntilDone:NO]; 

EDIT: y el cambio meth2 esperar un NSNumber en lugar de un int.

+1

Eso causará un bloqueo en tiempo de ejecución porque también necesita modificar la firma del método para tomar 'NSNumber' –

6

Envolver el número entero en un NSNumber antes de pasarlo:

int next_int = 1 
NSNumber *theNumber = [NSNumber numberWithInt:next_int]; 
[self performSelectorOnMainThread:@selector(meth2:) withObject:theNumber waitUntilDone:NO]; 

Luego, su -meth2: método podría ser algo como esto:

- (void)meth2:(NSNumber*)theNumber 
{ 
    int next_int = [theNumber intValue]; 
    // do whatever 
} 
3

Es un poco de un truco, pero esto funciona bajo ARC:

int next_int = 1; 
[self performSelectorOnMainThread:@selector(meth2:) 
         withObject:(__bridge id)(void*)next_int 
        waitUntilDone:NO]; 

El __bridge palabra clave le dirá al compilador para ignorar el recuento de referencias bajo ARC, pero requiere un puntero, por lo que primero tiene que convertir el int en un puntero de vacío de estilo C. Cuando su método recibe el mensaje, tratará ese puntero de objeto como si fuera un entero.

Nota: Si puede cambiar el método para tomar un NSNumber en lugar de un entero, entonces esa sería la solución "adecuada". Lamentablemente, eso no siempre es posible.

+0

Este es un buen truco si quiere pasar una enumeración, como cuando se establece una propiedad enum; ej. '[cell performSelector: @selector (setSortOrder :) withObject: (__ bridge id) (void *) order];' – tiritea

Cuestiones relacionadas