0

我有一个 CCLayer,我想在其中添加许多按钮。我用这个初始化函数创建了 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;

}

这个初始化函数会将按钮添加到图层中,并且我正在管理 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 回答