[英]C-style array of pointers to Objective-C objects under ARC
我有一個指向Objective-C實例的2D數組,以跟蹤地圖網格上的游戲對象。 現在我將我的代碼轉換為ARC,Xcode指出了錯誤。 我知道指向對象的指針不允許作為結構成員,但這個讓我(差點)措手不及。
我理解ARC約束背后的基本原理,但是:
在網格中查找對象時,我無法負擔Objective-C數組的開銷
對象本身已經由同一類中定義的NSArray
ivar擁有,該類具有作為ivar的C風格網格; c風格的數組只是一個方便的結構化快捷方式。 此外,當從擁有的NSArray
中刪除對象時,我將相應的網格槽設置為NULL
。
也就是說,2D數組(網格)只是快速(但是愚蠢)指向安全保留在其他地方的對象( NSArray
ivar)的集合。
有沒有辦法擺脫使用演員陣容? 例如,將我的網格定義並分配為:
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;
使用演員陣容繞過ARC是一個壞主意。 更好的方法是為map.m 禁用ARC (或將查找部分分解為單獨的類)。然后使用retain
/ release
和你喜歡的C結構在其中進行手動內存管理,只要你做它正確它將正常工作,你將能夠從其他類調用它,避免嵌套NSArrays
等的開銷。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.