3

我试图在一个数组中跟踪我的精灵,在图层中添加和删除它们,然后最终将它们从数组中清除。

我正在使用以下代码:

Sprite * Trees[50];
Layer * Forest;

Forest =  [Layer node];
Forest.isTouchEnabled = YES;
[self addChild:Forest z:30];

// do this a bunch of times
Trees[0] = [[Sprite spriteWithFile:@"mytree.png"] retain];
[Trees[0] setPosition:cpv(240,160)];
[Forest addChild:Trees[0] z:5];

然后当我想摧毁一棵树时,我使用:

[Forest removeChild:Trees[0] cleanup:YES];
[Trees[0] release];

我的问题是,当我查看 Instruments 时,我永远不会回收该内存,永远不会有下降。我认为通过释放精灵可以释放内存。我这样做完全错了吗?

4

3 回答 3

4

我知道当你使用 cocos2d 的模拟器时,内存看起来并没有被释放,所以你必须在设备上运行它才能准确了解正在发生的事情。

这里有一个关于 cocos2d 和内存的很好的讨论。

我注意到的是,您创建和保留的所有内容都必须释放,但在我这样做之前它不会从内存中释放:

[[TextureMgr sharedTextureMgr] removeAllTextures]; 

这将释放内存。

这是一个更大的例子:

Sprite * sPopup = [[Sprite spriteWithFile:@"popup.png"] retain];
    sPopup.position = cpv(240,440);
    [self addChild: sPopup z:2];
[sPopup release];

然后,当我在另一个函数中完成 sPopup 时,我有这个:

[[TextureMgr sharedTextureMgr] removeAllTextures]; 

并且内存被释放。

于 2009-05-14T01:26:20.487 回答
3

我的怀疑是你“过度”保留:

Trees[0] = [[Sprite spriteWithFile:@"mytree.png"] retain];

如果 Trees 是函数中的局部变量,如果 spriteWithFile 返回具有自动释放功能的 Sprite,则在这种情况下您不必保留。

Apple 文档中关于延迟发布的部分对此进行了进一步讨论。总而言之,自动释放的接收者保证让对象在其范围内有效。如果您需要超出函数范围的对象(例如 Trees 是类的属性),那么是的,在这种情况下,您需要一个保留(或者只是合成一个配置为保留的属性)。

通过发出额外的保留,您的保留计数可能总是太高(永远不会达到 0),因此您的对象不会被垃圾收集。

为了更好地衡量,我建议您也回顾一下关于 objects 有效性的这一段

于 2009-03-21T16:11:18.450 回答
0

即使您调用 [Trees[x] release],我相信您仍然需要从数组中“删除”该项目,例如 Trees[x] = nil 或其他东西,因为数组本身仍然包含该对象。

Sprite 创建中的“保留”也不是必需的,因为 [Forest addChild:z:] 也会在其上放置保留(afaik)。

于 2009-04-11T00:13:39.857 回答