2012-09-20 12 views
6

En mi clase tengo una propiedad dispatch_queue_t declaró así:La aplicación se bloquea después de la actualización de Xcode a 4.5. Asignar el objeto retenido a la variable unsafe_unretained

@property (nonatomic, assign) dispatch_queue_t queue; 

Luego, en mi método init que hago:

- (id)initWithServerUrls: (NSString*)serverUrls 
{ 
    if (self = [super init]) 
    { 
     _queue = dispatch_queue_create("com.xxx.my_send_queue", DISPATCH_QUEUE_SERIAL); 
    } 

    return self; 
} 

En Xcode 4.4.1 y funcionó no causó ningún problema (la aplicación probó + en la tienda de aplicaciones). Ahora después de actualizar a Xcode 4.5 la aplicación se bloquea con EXC_BAD_ACCESS y Xcode me da una advertencia en esa línea que dice:

de asignar el objeto retenido a la variable unsafe_unretained; objeto se lanzará después de la asignación

Apple actualizó el compilador en Xcode 4.5 de LLVM 4.0 a LLVM 4.1 pero no tengo idea de por qué mi código está fallando en este momento.

Pasé por el código y el bloqueo ocurre justo después de esa línea. ¿Tiene alguna idea de lo que puede estar mal y cómo puedo solucionarlo?

SOLUCIÓN:

me las arreglé para conseguir que funcione con ambos SDK. Acabo de añadir:

#if OS_OBJECT_USE_OBJC 
@property (nonatomic, strong) dispatch_queue_t queue; // this is for Xcode 4.5 with LLVM 4.1 and iOS 6 SDK 
#else 
@property (nonatomic, assign) dispatch_queue_t queue; // this is for older Xcodes with older SDKs 
#endif 

espero que alguien le resulta útil

+0

self._queue = dispatch_queue_create ... ¿lo arregla? - agregando el "yo"." –

+0

No, sigue igual, se bloquea. Advertencia también está allí. – RaffAl

+0

que" Asignando objeto retenido "significa que el resultado de dispatch_queue_create (... y" a variable unwafe_unretained "significa el _queue. Y si el @synthetize doesn ' t solve (porque está en Constructor) que de alguna manera necesita manipular el dispatch_queue_create (valor devuelto, ¿podría publicar ese objeto, qué devuelve? –

Respuesta

13

primer lugar, si la plataforma de destino es 5+, te recomiendo la construcción con el iOS 5 SDK. Construir con un SDK posterior y configurar el "objetivo" puede funcionar, pero tiene muchos problemas (uno de los más importantes es que no obtiene ayuda del compilador para encontrar lugares donde haya utilizado métodos no compatibles). Entonces respuesta 1: necesitas iOS 5, compila contra iOS 5 y esto no debería importar.

En iOS 6, dispatch_queue_t es un objeto ObjC. Esto es una gran mejora. Significa que solo puede crear propiedades strong y que ARC se encargará del resto. Si apuntas a iOS 6, esto debería funcionar.

Si necesita construir el mismo código para iOS 5 e iOS 6, necesita saber cuál es cuál para poder administrar la memoria cuando la necesita y dejarla fuera cuando no la necesite. La prueba correcta para usar es #if OS_OBJECT_USE_OBJC. Recuerde, este es un tiempo de compilación cheque. Solo es aplicable para tratar con el código que desea escribir en diferentes SDK. Para un SDK dado, el comportamiento siempre será de una manera u otra.

Con respecto a la confusión "no segura" versus "asignar": Son lo mismo en este caso. "asignar" solo se aplica a no objetos. "unsafe_unretained" es lo que "assign" se convierte cuando se aplica a los objetos. Y en iOS6, dispatch_queue_t es un objeto.

Una solución más, en particular si realmente desea conservar el código de administración de memoria antiguo mientras compila con iOS 6 SDK. Puede pasar -DOS_OBJECT_USE_OBJC=0 al compilador. Esto se excluirá del nuevo modelo. Pero lo recomendaría como último recurso. Para obtener detalles, consulte os/object.h en el SDK. (Cmd-Shift-O, object.h)

+0

Gracias, esto aclara mucho! – RaffAl

+0

Necesito admitir ambas versiones de iOS, así que usaré la prueba que propusiste. Lo único que no entiendo ahora es cómo debería reemplazar el "@property (nonatomic, copy) CustomBlock completedBlock;" para que no se bloquee la aplicación en iOS 6. ¿Alguna idea de cómo resolverlo? – RaffAl

+2

Tenga en cuenta que si solo está * ejecutando * en ambas plataformas, debe compilar para iOS 5. Solo necesita esto si necesita el mismo código para compilar de manera diferente según la plataforma en la que esté compilando. Si necesita reemplazar la línea '@ property', simplemente envuélvala en la comprobación' # if' (si la variable está establecida, use 'copy'. Si la variable no está establecida, use' assign'.) –

Cuestiones relacionadas