1

私には2つのObjective-Cクラス、たとえばParentLayerとChildLayerがあります。子インスタンスで、親インスタンスのC配列にアクセスしたいと思います。だから私は私のcocos2dコードにこのようなものを持っています:

#define kNumOfElements 10
@implementation ParentLayer{
    int array[kNumOfElements];
}
-(id)init{
    //...
    for(int i=0;i<kNumOfElements;i++){
        array[i] = i;
    }
    [self addChild:childLayer];
    [childLayer initializeValues];
    //...
}
-(int *)getArray{
    return array;
}
@end

//meanwhile in my child layer...
//...
-(void)initializeValues{
    int *arr = [(ParentLayer *)[self parent] getArray];
    //NSLog(@"%d",arr[0]);   <------- this gives you bad exec access point, and looks like it's 0x00 for memory address
}
//...
  • これを行うための適切な方法は何ですか?
  • 多分私はCアレイの背後にある正しいメモリ管理を理解していません。私は、C配列を割り当てる必要がなく、スタック上で値で渡すことができるという印象を受けましたか?
  • また、私の親インスタンスはまだ存在するべきではありませんか?親のivarとしてC配列を配置すれば、破壊されるべきではないと思いました

どんな助けでも大歓迎です。ありがとう!

4

3 に答える 3

1

Objective Cでは、このためにプロパティを使用できます。

#define kNumOfElements 10

@interface  ParentLayer: NSObject
{
    int *array;
}
@property(nonatomic, assign) int *array;
@end

@implementation ParentLayer
-(id)init{
    //...
    self.array =(int*)malloc(sizeof(int) * kNumOfElements);

    for(int i=0;i<kNumOfElements;i++){
        self.array[i] = i;
    }
    [self addChild:childLayer];
    [childLayer initializeValues];
    //...
}
//-(int *)getArray{
//    return array;
//}

-(void)dealloc
{
   if(self.array)
   {
      free(self.array); self.array = NULL;
   }
   [super dealloc];
}    

@end


-(void)initializeValues{

    ParentLayer *player = (ParentLayer *)[self parent] ;
    int *arr = player.array;
    //NSLog(@"%d",arr[0]);   <------- this gives you bad exec access point, and looks like it's 0x00 for memory address
}
于 2012-11-18T06:26:38.883 に答える
1

これを行うための適切な方法は何ですか?

理想的には、Cスタイルの配列ポインタをそれを所有するオブジェクトの外部に渡さないでください。オブジェクトの割り当てが解除された後、コードの一部が配列を使用しようとしたり、最後を超えて書き込みを行ったりすると、あらゆる種類の問題が発生します。参照がオブジェクトのソースファイルを離れないようにすることができれば、これが発生しないことを保証する方が簡単です。

多分私はCアレイの背後にある正しいメモリ管理を理解していません。私は、C配列を割り当てる必要がなく、スタック上で値で渡すことができるという印象を受けましたか?

それほど単純ではありません。

Cスタイルの配列は単なるメモリアドレスです。それでおしまい。要素の数など、オブジェクトがカウントを保持する可能性のある他の有用な情報は持ち歩きません。

このような配列を宣言する場合:

int array[100];

次に、宣言を配置した場所に応じて、メモリがスタックまたはヒープのいずれかに割り当てられます。関数またはメソッド内のローカル変数の場合は、スタック上にあります。グローバルスコープまたはオブジェクトのメンバー変数にある場合は、ヒープ上にあります。

さらに、それがインスタンス変数である場合、オブジェクトを保持するために割り当てられたメモリのブロック内に100int相当のメモリを実際に取っておきます。それは別のものではありません。

arrayは単なるメモリアドレスなので、基本的には参照によって渡します。技術的には、アドレスを値で渡しますが、メモリに加えた変更は、同じアドレスを見ている人に表示されるため、参照渡しのように機能します。

また、私の親インスタンスはまだ存在するべきではありませんか?親のivarとしてC配列を配置すれば、破壊されるべきではないと思いました

あなたがそれをコーディングした方法では、その配列は親オブジェクトが存在する限り有効です。親の割り当てが解除されると、そのメモリを再利用できます。ただし、array変数は単なるメモリアドレスであるため、それが指すデータが有効かどうかを知る方法はありません。これは、オブジェクトではなくCスタイルの配列を使用することの危険性です。

最後の行はNULL(0)アドレスを示しているので、私の推測で[self parent]はnilです。それは0を入れarrます; NULLを逆参照しようとすると、例外が発生します。

于 2012-11-18T06:35:20.533 に答える
1

ベンザドの投稿に返信を追加できないようです。ただし、オブジェクトの宣言方法によっては、自動的に割り当てが解除される場合があります。確実に保持するには、retainキーワードを使用します。

[obj retain];

特にcocos2dフレームワークを使用すると、かなりの数の自動リリースオブジェクトがあります。通常、initWithは自動リリースではありません。

于 2012-11-18T07:23:26.487 に答える