在ARC下的Objective-C对象的C风格数组指针
我有一个指向Objective-C实例的二维数组来跟踪地图网格上的游戏对象。 现在我正在将我的代码转换到ARC,Xcode指出了错误。 我知道指向对象的指针不允许作为struct成员,但是这个引起了我(几乎)的不安。
我了解ARC约束的基本原理,但是:
-
在网格中查找对象时,我无法承受Objective-C数组的开销
-
这些对象本身已经被一个在同一个类中定义的具有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
等开销。