在ARC下的Objective-C对象的C风格数组指针

我有一个指向Objective-C实例的二维数组来跟踪地图网格上的游戏对象。 现在我正在将我的代码转换到ARC,Xcode指出了错误。 我知道指向对象的指针不允许作为struct成员,但是这个引起了我(几乎)的不安。

我了解ARC约束的基本原理,但是:

  1. 在网格中查找对象时,我无法承受Objective-C数组的开销

  2. 这些对象本身已经被一个在同一个类中定义的具有C风格的网格的NSArray伊娃所拥有, C风格的数组只是一个方便结构化的捷径。 此外,当从拥有的NSArray中移除对象时,我将相应的网格槽设置为NULL

也就是说,二维数组(网格)只是一个快速(但愚蠢)指针对象安全地保留在其他地方( NSArray伊娃)的集合。

有没有办法摆脱这个使用强制转换? 例如,定义和分配我的网格为:

 void*** _grid; 

代替

 MyMapObjectClass*** _grid 

并在设置或获取每个插槽中的指针时,在void* < – > MyMapObjectClass*之间使用(适当地桥接)

编辑 :所以这里是我如何解决它

我如上所述改变了伊娃的声明。 另外,当设置我的查询网格的条目时,我这样做了:

 // (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; 

在访问(x,y)处的对象时,我会做相反的事情:

 MyMapObjectClass* object = (__bridge MyMapObjectClass*) _grid[x][y]; [object performSomeMethod]; // etc... 

从地图中删除对象时,我这样做:

 MyMapObjectClass* object = (__bridge MyMapObjectClass*) _grid[x][y]; [_objectArray removeObject:object]; _grid[x][y] = NULL; 

地图对象在游戏开始时被创build一次,并根据游戏进度被移除。 如果我需要replace另一个地图对象,我会这样做:

 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; 

使用强制转换ARC通常是一个糟糕的主意。 更好的办法是为你的map.m 禁用ARC (或者把查找部分分解成一个单独的类),然后用retain / release和你喜欢的C结构在里面进行手动内存pipe理,只要你做它正确,它会正常工作,你将能够从其他类调用它,避免嵌套NSArrays等开销。