0

多くのボタンを追加したい CCLayer があります。この init 関数を使用してクラス MyButton を作成しました。

-(id) initWithLayer:(MyLayer *)theLayer andDictionary:(NSDictionary *)data {
  self = [super init];
  if (self != nil)
  {
    self.layer = theLayer;

    self.tag = [[data objectForKey:@"day"] intValue];
    _layerZ = [[data objectForKey:@"z"] intValue];
    _closedCard = [[CCSprite alloc] initWithFile:[data objectForKey:@"file"]];
    _openedCardFile = [[NSString alloc] initWithString:[data objectForKey:@"open_card"]];

    CCMenuItemImage *itemImage = [CCMenuItemImage
                                        itemFromNormalSprite:_closedCard
                                        selectedSprite:nil
                                        target:self
                                        selector:@selector(displayCard:)];

    CGPoint position = CGPointFromString([data objectForKey:@"position"]);
    _position = ccp(position.x, position.y);
    itemImage.position = _position;
    itemImage.tag = self.tag;

    _theCardButton = [CCMenu menuWithItems:itemImage, nil];
    _theCardButton.position = CGPointZero;
    [self.layer addChild:_theCardButton z:_layerZ];
} 
return self;

}

この init 関数はレイヤーにボタンを追加し、MyButton クラスですべての動作 (動き、画像​​の変更) を管理しています。

そのため、レイヤーはすべての MyButton インスタンスに送信されています。各ボタンが離されるまで、レイヤーは dealloc メソッドを呼び出しません。

これらのボタンは、配列を介してレイヤーに追加されています。

_buttons = [[NSMutableArray alloc] init];
for (NSDictionary *buttonData in buttonsArray) {
   MyButton *btn = [[MyButton alloc] initWithLayer:self andDictionary:buttonData];
   [_buttons addObject:btn];
   [btn release];
}

私の問題は、このシーンを置き換えると、MyButton の dealloc メソッドが呼び出されず、メモリが解放されないことです。これは、[_buttons release] がレイヤーの dealloc メソッドにあり、これも呼び出されていないためです。レイヤーが各ボタンに渡されました。

それは混乱です。このメモリの問題を解決するための最良の方法を誰か教えてもらえますか?

- 編集

replaceScene を呼び出す前にボタンの配列を手動で解放しようとすると、各ボタンが dealloc を呼び出しますが、次のエラー メッセージが表示されます。

[CCMenu pauseSchedulerAndActions]: message sent to deallocated instance 0x131a0670
4

2 に答える 2

0

ボタンに CCLayer を保持しないでください。これにより、上記の状況での漏れを防ぐことができます。

于 2012-07-11T11:20:15.340 に答える
0

メソッドでレイヤーを保持しますinitWithLayer:andDictionary:か? 次に、保持サイクルがあります。

retainオブジェクトにメッセージを送信すると、保持カウントが 1 増加します。メッセージを送信するとrelease、保持カウントが 1 減少します。deallocメッセージは、保持カウントが 0 になるとオブジェクトに送信されます。

メッセージがレイヤーにrelease送信されると、保持カウントは 0 に達しません_buttons。レイヤーの保持カウントが 0 に達することはないため、レイヤーdeallocが呼び出されることはなく、ボタンがリリース メッセージを受け取ることも、dealloc呼び出されることも、レイヤーを解放することもありません。サイクル。

保持サイクルを回避するために、子オブジェクトはその親または親の親を保持してはなりません。

于 2012-07-11T11:32:29.833 に答える