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:
que no pueden permitirse los gastos generales de las matrices de Objective-C al buscar objetos en la red, y
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 propiedadNSArray
, configuro la ranura de la red correspondiente enNULL
.
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;
¿dónde está la línea de código que señala ARC? –
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 ... –
Es curioso, algunos de los moldes son 'sugeridos' por la función de autocorrección de Xcode, pero algunos simplemente se marcan como errores. –