将cclayer传递给我的对象时出现内存问题

时间:2012-07-11 10:40:37

标签: memory-management cocos2d-iphone dealloc cclayer ccmenuitem

我有一个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

2 个答案:

答案 0 :(得分:0)

不要将CCLayer保留在按钮中。这样可以防止它在所描述的情况下泄漏。

答案 1 :(得分:0)

您是否在initWithLayer:andDictionary:方法中保留了图层?然后你有一个保留周期。

当您向对象发送retain消息时,您将其保留计数增加1.当您发送release消息时,您将保留计数减少1. dealloc消息将被发送到对象,当其保留计数达到0时。

release消息发送到您的图层时,其保留计数不会达到0,因为_buttons中的每一个都为自己保留了它。因为图层的保留计数永远不会达到0,所以永远不会调用它的dealloc,按钮永远不会得到释放消息,永远不会调用它们dealloc,永远不会释放图层等等。周期。

为了避免保留周期,子对象绝不能保留任何父母或父母的父母。