我正在尝试在数组中跟踪我的精灵,添加和删除 它们来自层,然后最终将它们从阵列中清除。
我正在使用以下代码:
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];
我的问题是,当我查看乐器时,我永远不会回收 记忆中,永远不会退缩。我以为是的 释放精灵会释放内存。我这样做了吗 完全错了?
答案 0 :(得分:4)
我知道当你使用带有cocos2d的模拟器时,内存看起来不像它正在被释放,所以你必须在设备上运行它才能准确了解正在发生的事情。
关于cocos2d和内存的讨论很here。
我注意到你必须释放你创建和保留的所有东西,但是在我这样做之前它不会从内存中释放出来:
[[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];
并释放内存。
答案 1 :(得分:3)
我怀疑你是“过度”保留:
Trees[0] = [[Sprite spriteWithFile:@"mytree.png"] retain];
如果Trees是函数中的局部变量,那么如果spriteWithFile返回带有自动释放的Sprite,则不必保留。
apple documentation discusses this further中有关延迟释放的部分。它的长短是保证自动释放的接收者在其范围的持续时间内使对象有效。如果你需要超出函数范围的对象(例如Trees是类的属性)那么是,在这种情况下你需要一个retain(或者只是合成一个配置为保留的属性)。
通过发出额外的保留,你的保留计数可能总是太高(永远不会达到0),因此你的对象不会被垃圾收集。
为了更好的衡量标准,我建议reviewing this paragraph as well that talks about the validity of objects。
答案 2 :(得分:0)
即使你调用[Trees [x] release],我相信你仍然需要从数组中“删除”该项,比如Trees [x] = nil或者其他东西,因为数组本身仍然包含该对象。
Sprite创建中的'retain'也不是必需的,因为[Forest addChild:z:]也会在其上放置一个retain(afaik)。