2012-06-22 3 views
10

Tengo una matriz 2D de punteros a instancias de Objective-C para realizar un seguimiento de los objetos del juego en una cuadrícula de mapa. Ahora estoy haciendo la transición de mi código a ARC, y Xcode señaló el error. Sabía que los punteros a los objetos no están permitidos como miembros de la estructura, pero este me pilló (casi) desprevenido.Conjunto de punteros estilo C para objetos Objective-C bajo ARC

entiendo la razón de ser de las restricciones ARC, pero:

  1. que no pueden permitirse los gastos generales de las matrices de Objective-C al buscar objetos en la red, y

  2. Los objetos ellos mismos ya son propiedad de un NSArray ivar definido en la misma clase que tiene la grilla C-style como un ivar; la matriz c-style es solo un atajo convenientemente estructurado. Además, cuando se eliminan objetos de la propiedad NSArray, configuro la ranura de la red correspondiente en NULL.

Es decir, la matriz 2D (rejilla) es sólo una colección de punteros rápidos (pero mudos) a los objetos retenidos de forma segura en otro lugar (la NSArray Ivar).

¿Hay alguna manera de salirse con la suya con los moldes? Por ejemplo, definir y alloc mi rejilla como:

void*** _grid; 

en lugar de

MyMapObjectClass*** _grid 

y utilizar (apropiadamente puente) arroja entre void* < ->MyMapObjectClass* la hora de establecer o conseguir los punteros en cada ranura?

EDITAR: Así que aquí es cómo lo resolví

he cambiado la declaración Ivar como se describió anteriormente. Además, al establecer una entrada de mi rejilla de búsqueda, lo hice:

// (Done **Only Once** at map initialization) 
// _objectArray is an instance of NSMutableArray 

MyMapObjectClass* mapObject = [[MyMapObjectClass alloc] init]; 

// ...configure map object, etc... 

// Add to Obj-C array: 
[_objectArray addObject:mapObject]; 

// Add pointer to 2D C array: 
_grid[i][j] = (__bridge void*)mapObject; 

Al acceder al objeto en (x, y), hago lo contrario:

MyMapObjectClass* object = (__bridge MyMapObjectClass*) _grid[x][y]; 

[object performSomeMethod]; 

// etc... 

Al retirar el objeto del mapa, hago esto:

MyMapObjectClass* object = (__bridge MyMapObjectClass*) _grid[x][y]; 

[_objectArray removeObject:object]; 

_grid[x][y] = NULL; 

mapa objetos se crean una vez al principio del juego, y se eliminan de acuerdo con el progreso del juego. Si necesito reemplazar un objeto de mapa para otro, lo haría esto:

MyMapObjectClass* oldObject = (__bridge MyMapObjectClass*) _grid[x][y]; 
// (should mark as weak?) 

[_objectArray removeObject:oldObject];  
_grid[x][y] = NULL; 

MyMapObjectClass* newObject = [[MyMapObjectClass alloc] init]; 

[_objectArray addObject:newObject]; 

_grid[x][y] = (__bridge void*)newObject; 
+0

¿dónde está la línea de código que señala ARC? –

+0

Xcode no parece señalar todos los errores a la vez, sino en lotes de 4-12. Arreglas un poco, y los siguientes aparecen en el siguiente control. El primer error apareció en la declaración ivar del conjunto de C. Y ahora, cada asignación o comparación entre obj-c puntero y void * se está señalizando. Lo estoy arreglando ahora, y parece que __bridge debería funcionar ... –

+0

Es curioso, algunos de los moldes son 'sugeridos' por la función de autocorrección de Xcode, pero algunos simplemente se marcan como errores. –

Respuesta

2

eludir arco utilizando moldes es generalmente una mala idea. La mejor manera sería disable ARC para su map.m (o simplemente dividir la parte de búsqueda en una clase separada). Luego realice la administración manual de la memoria dentro de ella con retain/release y las estructuras C que desee, siempre que lo haga correctamente funcionará bien y podrá llamarlo desde otras clases, evitando la sobrecarga de NSArrays anidados ...

+0

Pero los indicadores que tengo funcionan como __unsafe_unretained. No estoy evitando ARC, solo uso __bridge; No debe haber ningún problema. Mantengo el NSArray y el array C sincronizados. Los objetos son retenidos por NSArray (según ARC). No hay peligro de punteros colgantes. –

+1

Para ponerlo más claro: tengo un NSArray compatible con ARC que posee mis objetos, 100% Objective-C, 100% ARC. ** Además **, tengo una 'tabla de búsqueda' para obtener acceso rápido a mis objetos en forma de fila/columna. Las entradas de la tabla se actualizan correctamente a NULL cuando elimino un objeto del NSArray (que se desasigna), para evitar eliminar referencias a un zombie. –

+2

Todavía recomendaría descomponer en factores en un archivo separado y deshabilitar ARC para ese archivo, ya que es una solución más a prueba de futuro. Si Apple alguna vez decide cambiar la semántica, no terminará con errores de compilación para versiones incompletas. Sin embargo, tu solución funcionará. –

Cuestiones relacionadas