问题描述
我有指针Objective-C的实例的二维数组来跟踪游戏对象在地图上的坐标。
现在我转变我的code为弧形,和X code指出的错误。我知道对象指针不允许作为结构成员,但是这一次抓住了我(几乎)猝不及防。
据我所知,ARC背后的基本原理约束,但是:
-
查找在网格对象时我不能客观-C数组的开销,以及
-
本身已经在具有C风格的网格,伊娃相同的类中定义的
的NSArray
伊娃拥有的对象; C风格的数组仅仅是一个方便快捷的结构。 Futhermore,当对象从所属的NSArray
去掉,我设置了相应的网格槽NULL
。
也就是说,二维数组(网格)只是一个快速(但哑)三分球安全地保留在其他地方(即的NSArray
伊娃)对象的集合。
有没有办法逃脱这个使用强制转换?例如,定义和ALLOC我格为:
无效*** _grid;
而不是
MyMapObjectClass *** _grid
和使用(适当桥接)之间蒙上无效*
< - > MyMapObjectClass *设置或获取时
在每个时隙指针?
修改:因此,这里是我如何解决它。
我改变了伊娃声明如上所述。此外,设置我的查询网格的条目时,我这样做:
//(完成**仅**一旦在地图初始化)
// _objectArray是的NSMutableArray的一个实例MyMapObjectClass * MapObject的= [[MyMapObjectClass的alloc]初始化];// ...配置地图对象,等等。//添加到的OBJ-C数组:
[_objectArray ADDOBJECT:MapObject的]。//添加指向二维数组c:
_grid [I] [J] =(__bridge无效*)MapObject的;
在访问时(X,Y)的对象,我却反其道而行之:
MyMapObjectClass *对象=(__bridge MyMapObjectClass *)_grid [X] [Y][对象performSomeMethod]//等等...
当从地图上删除的对象,我这样做:
MyMapObjectClass *对象=(__bridge MyMapObjectClass *)_grid [X] [Y][_objectArray的removeObject:对象]。_grid [X] [Y] = NULL;
Map对象是根据游戏进度在游戏开始创建一次,并删除。如果我需要的替换作为另一地图对象,我会做这样的:
MyMapObjectClass *的OLDobject =(__bridge MyMapObjectClass *)_grid [X] [Y]
//(应标记为弱?)[_objectArray的removeObject:的OLDobject];
_grid [X] [Y] = NULL;MyMapObjectClass * NEWOBJECT = [[MyMapObjectClass的alloc]初始化];[_objectArray ADDOBJECT:NEWOBJECT];_grid [X] [Y] =(__bridge无效*)NEWOBJECT;
使用ARC规避一般铸件是一个坏主意。更好的方法是disable ARC 的为您map.m(或爆发只是部分查找到一个单独的类)。然后做在里面手动内存管理,保留
/ 发布
和C结构你喜欢,只要你正确地做到这一点它会正常工作,你将能够从其他类调用它,避免嵌套的<$ C $的开销C> NSArrays 等
I have a 2D array of pointers to Objective-C instances to keep track of game objects on a map grid.Now I am transitioning my code to ARC, and Xcode pointed the error. I knew pointers to objects aren't allowed as struct members, but this one caught me (almost) off guard.
I understand the rationale behind the ARC constrains, but:
I can't afford the overhead of objective-C arrays when looking up objects in the grid, and
The objects themselves are already owned by an
NSArray
ivar defined in the same class that has the C-style grid as an ivar; the c-style array is only a conveniently structured shortcut. Futhermore, when objects are removed from the owningNSArray
, I set the corresponding grid slot toNULL
.
That is, the 2D array (grid) is just a collection of fast (but dumb) pointers to objects safely retained somewhere else (the NSArray
ivar).
Is there a way to get away with this using casts? For example, define and alloc my grid as:
void*** _grid;
instead of
MyMapObjectClass*** _grid
and use (appropriately bridged) casts between void*
<-> MyMapObjectClass*
when setting or getting the pointers in each slot?
EDIT: So here is how I solved it
I changed the ivar declaration as described above. In addition, when setting an entry of my look-up grid, I did this:
// (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;
When accessing the object at (x,y), I do the opposite:
MyMapObjectClass* object = (__bridge MyMapObjectClass*) _grid[x][y];
[object performSomeMethod];
// etc...
When removing the object from the map, I do this:
MyMapObjectClass* object = (__bridge MyMapObjectClass*) _grid[x][y];
[_objectArray removeObject:object];
_grid[x][y] = NULL;
Map objects are created once at the beginning of the game, and removed according to game progress. If I need to replace a map object for another, I would do this:
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;
Circumventing ARC using casts is generally a bad idea. The better way would be to disable ARC for your map.m (or break out just the lookup part into a separate class).Then do manual memory management inside it with retain
/ release
and the C structures you like, as long as you do it correctly it will work fine and you will be able to call it from other classes, avoiding the overhead of nested NSArrays
etc..
这篇关于指针下的ARC的Objective-C对象的C数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!