将 cclayer 传递给我的对象时的内存问题
Posted
技术标签:
【中文标题】将 cclayer 传递给我的对象时的内存问题【英文标题】:memory issue when passing the cclayer to my objects 【发布时间】:2012-07-11 10:40:36 【问题描述】:我有一个 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
【问题讨论】:
您创建了一个保留周期。不要在 init 中传入 layer。如果图层是节点的父级,则可以使用 parent 属性。在所有其他情况下,请考虑将层设为单例类。 【参考方案1】:您是否在initWithLayer:andDictionary:
方法中保留该层?然后你有一个保留周期。
当您向一个对象发送retain
消息时,它的保留计数增加1。当您发送release
消息时,您的保留计数减少1。dealloc
消息在其保留计数达到时发送到对象0.
当release
消息发送到你的层时,它的保留计数不会达到0,因为_buttons
中的每一个都为自己保留了它。因为层的保留计数永远不会达到 0,所以它的 dealloc
永远不会被调用,按钮永远不会收到释放消息,永远不会被调用 dealloc
,永远不会释放层等等。循环。
为避免保留循环,子对象绝不能保留其任何父对象或任何父对象的父对象。
【讨论】:
【参考方案2】:不要将 CCLayer 保留在按钮中。这将防止它在所描述的情况下泄漏。
【讨论】:
发布您的initWithLayer:andDictionary:
方法
我已经编辑了帖子,添加了 initWithLayer 函数。谢谢!
声明您的图层属性为已分配,或者,如果您使用 ARC,则将其声明为弱属性以上是关于将 cclayer 传递给我的对象时的内存问题的主要内容,如果未能解决你的问题,请参考以下文章