将 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 传递给我的对象时的内存问题的主要内容,如果未能解决你的问题,请参考以下文章

什么?面试官问我Java内存模型!这不得给我加薪?

什么?面试官问我Java内存模型!这不得给我加薪?

cocos2d-x中如何释放CCLayer的子节点

如何将对象(或关联数组)作为属性值传递给我的 Web 组件

将本地变量分配给属性时的内存泄漏弧

将二维数组从 C# 传递到 C++