我有一个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
答案 0 :(得分:0)
不要将CCLayer保留在按钮中。这样可以防止它在所描述的情况下泄漏。
答案 1 :(得分:0)
您是否在initWithLayer:andDictionary:
方法中保留了图层?然后你有一个保留周期。
当您向对象发送retain
消息时,您将其保留计数增加1.当您发送release
消息时,您将保留计数减少1. dealloc
消息将被发送到对象,当其保留计数达到0时。
当release
消息发送到您的图层时,其保留计数不会达到0,因为_buttons
中的每一个都为自己保留了它。因为图层的保留计数永远不会达到0,所以永远不会调用它的dealloc
,按钮永远不会得到释放消息,永远不会调用它们dealloc
,永远不会释放图层等等。周期。
为了避免保留周期,子对象绝不能保留任何父母或父母的父母。