10

マップグリッド上のゲームオブジェクトを追跡するために、Objective-Cインスタンスへのポインターの2D配列があります。現在、コードをARCに移行していますが、Xcodeがエラーを指摘しました。オブジェクトへのポインタが構造体メンバーとして許可されていないことは知っていましたが、これは(ほとんど)不意を突かれました。

ARCの制約の背後にある理論的根拠は理解していますが、次のようになります。

  1. グリッド内のオブジェクトを検索するときにObjective-C配列のオーバーヘッドを支払う余裕はありません。

  2. NSArrayオブジェクト自体は、 ivarと同じCスタイルのグリッドを持つ同じクラスで定義されたivarによってすでに所有されています。c-style配列は、便利な構造のショートカットにすぎません。さらに、オブジェクトが所有から削除されるとNSArray、対応するグリッドスロットをに設定しNULLます。

つまり、2D配列(グリッド)は、他の場所(NSArrayivar)に安全に保持されているオブジェクトへの高速(ただしダム)ポインターのコレクションにすぎません。

キャストを使用してこれを回避する方法はありますか?たとえば、グリッドを次のように定義して割り当てます。

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;

マップオブジェクトは、ゲームの開始時に1回作成され、ゲームの進行状況に応じて削除されます。マップオブジェクトを別のオブジェクトに置き換える必要がある場合は、次のようにします。

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;
4

1 に答える 1

2

キャストを使用してARCを回避することは、一般的に悪い考えです。より良い方法は、map.mのARCを無効にする(またはルックアップ部分だけを別のクラスに分割する)ことです。次に、正しく実行する限り、retain/および任意のC構造体を使用してその内部で手動のメモリ管理を実行します。正常に動作し、ネストなどreleaseのオーバーヘッドを回避して、他のクラスから呼び出すことができます。NSArrays

于 2012-06-22T12:21:50.383 に答える