2011-08-05 13 views
27

estoy convirtiendo mi cliente toma a ARC:error "Pasando dirección del objeto que no es local a __autoreleasing parámetro de escritura no simultánea"

- (id)initWithHostname:(NSString *)hostname AndPort:(NSInteger)port 
{ 
    if((self = [super init])) 
    { 
     oBuffer = [[NSMutableData alloc] init]; 
     iBuffer = [[NSMutableData alloc] init]; 

     iStream = [[NSInputStream alloc] init]; 
     oStream = [[NSOutputStream alloc] init]; 

     [NSStream getStreamsToHost:[NSHost hostWithName:hostname] port:port inputStream:&iStream outputStream:&oStream]; 

     ... 
    } 

    return self; 
} 

El error que tengo es:

file://localhost/...foo.m: error: Automatic Reference Counting Issue: Passing address of non-local object to __autoreleasing parameter for write-back

en esta línea en "& iStream"/"& ostream"

[NSStream getStreamsToHost:[NSHost hostWithName:hostname] port:port inputStream:&iStream outputStream:&oStream]; 

Cualquier ayuda?

+0

dada la nueva ARC es, que podría hacer mejor pedir esto en los foros de desarrolladores . – jtbandes

+0

Seguro, por supuesto;) – kilianc

Respuesta

37

Este error generalmente se debe a que la dirección de variable no local se pasa a un método. Porque la variable se declara como __strong por defecto, mientras que el parámetro del método es __suave, así que declare el parámetro del método invocado como __strong, de esta manera: -(void)method:(id * __strong *)para.
Tenga en cuenta que el método en el archivo de cabecera (.h) debe ser declarado como el mismo del archivo .m

+0

Esta sugerencia resolvió el problema por completo. En mi caso, el código no ARC, libera el valor de ivar pasado y la otra solución de asignar el ivar a las variables temporales locales, pasarlo a la función de destino y reasignarlo de nuevo a ivar como lo sugiere @Rudy Velthuis, aunque resuelve el error del compilador. EXC_BAD_ACCESS error en el tiempo de ejecución ya que la memoria liberada todavía está colgando y se hace referencia dentro del código no ARC después de que se ha liberado. – Rajaraman

12

Creo que no deberías asignar ni iniciar las variables de iStream y oStream. Están destinados a recibir. Sin ARC esto simplemente crea dos pérdidas de memoria que pasan desapercibidas. Ahora su compilador usa ARC y luego importa. Las variables receptoras deben ser locales:

Así que trate de:

NSInputStream *iStream; 
    NSOutputStream *oStream; 

    oBuffer = [[NSMutableData alloc] init]; 
    iBuffer = [[NSMutableData alloc] init]; 

    [NSStream getStreamsToHost:[NSHost hostWithName:hostname] port:port inputStream:&iStream outputStream:&oStream]; 

Eso debería funcionar, AFAICT. Pero nota: no puedo probar esto aquí.

+0

Gracias Rudy, su código funciona. Pero necesito alguna explicación. Está utilizando dos punteros locales en lugar de mis punteros de instancia para 'iStream' y' oStream', por lo que no puedo tener una referencia inmediata a mis transmisiones. Esto se debe a que NSStream puede cambiar la transmisión en cualquier momento o ¿qué? – kilianc

+0

@kilianc: No lo sé. El mensaje de error se quejó de las variables no locales, por lo que supuse que deberían ser locales. No tengo un compilador de ARC para probarlo. Entonces, probablemente los asigne a las propiedades o ivars. –

+0

Hay una respuesta mejor aquí: http://stackoverflow.com/questions/7415301/automatic-reference-counting-issue-passing-address-of-non-local-object-to-aut – nduplessis

13

Cree dos variables locales, pase las direcciones de las mismas al método, luego asigne sus valores a los ivars después de que regrese.

Cuestiones relacionadas