指针下ARC Objective-C对象的C数组(C-style array of pointers

2019-06-25 16:04发布

我有指针Objective-C的情况下的2D阵列来追踪游戏对象上的地图网格。 现在我转变我的代码ARC,和Xcode中指出的错误。 我知道对象指针不允许作为结构成员,但是这一次抓住了我(几乎)猝不及防。

我理解的理由背后的ARC限制,但是:

  1. 在网格中查找对象时我不能客观-C数组的开销,

  2. 本身已经通过拥有的对象NSArray在具有C风格的网格,伊娃相同的类中定义的伊娃; C风格的数组仅仅是一个方便快捷的结构。 Futhermore,当对象从拥有除去NSArray ,我设置相应的格槽,以NULL

这就是2D阵列(网格)只是一个快速(但哑)指向留存安全别处对象(集合NSArray伊娃)。

有没有办法来摆脱这种使用强制转换? 例如,定义或Alloc我的网格为:

void*** _grid;

代替

MyMapObjectClass*** _grid

和使用(适当地桥接)之间投下void* < - > MyMapObjectClass*设置或获取指针在每个时隙时?

编辑 :因此,这里是我如何解决它

我改变了的ivar声明如上所述。 此外,设置我的查找电网的条目时,我这样做:

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

根据游戏进度在游戏开始创建地图对象一次,并删除。 如果我需要更换另一个地图对象,我这样做:

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;

Answer 1:

规避ARC使用强制转换通常是一个坏主意。 更好的办法是禁用ARC您map.m(或爆发只是查找部分成一个单独的类)。然后做手工的内存管理内配置有retain / release和你喜欢的C结构,只要你做它正确它将很好地工作,你将能够从其他类调用它,避免嵌套的开销NSArrays等。



文章来源: C-style array of pointers to Objective-C objects under ARC