我一直在针对我的应用程序运行Xcode的仪器分配工具,并发现使用Tilemaps的场景(CCNodes)在释放时不会释放所有内存。我有什么遗失的吗?
该项目使用ARC。
为了说明这一点,我创建了一个包含3个类文件的迷你项目,它将重现错误。类文件如下:
RedTest
YellowTest
GreenTest
所有三个文件都相似,因为它们都以相应的颜色显示相同大小的背景精灵。所有三个文件都有两个菜单按钮,允许活动场景被两个非活动场景中的一个替换。例如:RedTest有一个黄色和绿色按钮。当按下其中一个按钮时
[[CCDirector sharedDirector] replaceScene:
调用指令关闭活动场景并打开指定的新场景。因此,例如,按下RedTest中的黄色按钮将关闭RedTest并打开YellowTest。
行。当我在仪器的分配中运行时,我只关注[All Heap& amp;匿名VM .. Live Bytes]值。
首先调用RedTest.m(来自app delegate),字节数大约为2.50mb。我可以在所有3个场景之间切换,这个值保持不变。此时代码证明我们可以在不增加内存占用的情况下在所有场景之间切换。
现在是时候创建问题了:
在GreenTest.m中,我有两行注释掉,为背景创建一个瓦片地图而不是一个精灵。 当您注释掉精灵线并取消注释平铺贴图线时,我会看到以下行为:
启动时,RedTest.m显示2.50mb(如前所述)。当我按下绿色按钮并显示瓷砖地图时,val会跳到2.89mb左右。当我按下红色或黄色按钮时,内存会下降但保持在2.69mb。从这一点开始,内存将始终显示2.69mb(显示黄色或红色时)或绿色显示时显示2.89mb。
所以问题是 ...在打开和关闭绿色主题(带有平铺图的那个)之后,基本内存值已经从2.50mb爬升到2.69mb,即使GreenTest也是如此。 m应该已经解除分配。
下面列出了三个类文件:
// RedTest.m
#import "RedTest.h"
@implementation RedTest
-(id) init
{
if( (self=[super init]) ) {
// ask director for the window size
CGSize size = [[CCDirector sharedDirector] winSize];
//Add a background sprite.
CCSprite * background = [CCSprite spriteWithFile:@"RedBack.png"];
background.position = ccp(size.width * 0.5f,size.height * 0.5f);
[self addChild:background z:0];
//Add a simple two button menu
CCMenuItem *yellowButton = [CCMenuItemImage
itemWithNormalImage:@"YellowButton.png"
selectedImage:@"WhiteButton.png"
disabledImage:nil
target:self
selector:@selector(changeToYellow)];
CCMenuItem *greenButton = [CCMenuItemImage
itemWithNormalImage:@"GreenButton.png"
selectedImage:@"WhiteButton.png"
disabledImage:nil
target:self
selector:@selector(changeToGreen)];
CCMenu * coloursMenu = [CCMenu menuWithItems:yellowButton,greenButton,nil];
coloursMenu.position = CGPointZero;
yellowButton.position = ccp(size.width * 0.30f,size.height * 0.5f);
greenButton.position = ccp(size.width * 0.70f,size.height * 0.5f);
[self addChild:coloursMenu z:10];
}
return self;
}
-(void) changeToYellow {
[[CCDirector sharedDirector] replaceScene:[YellowTest node]];
}
-(void) changeToGreen {
[[CCDirector sharedDirector] replaceScene:[GreenTest node]];
}
@end
// YellowTest.m
#import "YellowTest.h"
@implementation YellowTest
-(id) init
{
if( (self=[super init]) ) {
// ask director for the window size
CGSize size = [[CCDirector sharedDirector] winSize];
//Add a background sprite.
CCSprite * background = [CCSprite spriteWithFile:@"YellowBack.png"];
background.position = ccp(size.width * 0.5f,size.height * 0.5f);
[self addChild:background z:0];
//Add a simple two button menu
CCMenuItem *redButton = [CCMenuItemImage
itemWithNormalImage:@"RedButton.png"
selectedImage:@"WhiteButton.png"
disabledImage:nil
target:self
selector:@selector(changeToRed)];
CCMenuItem *greenButton = [CCMenuItemImage
itemWithNormalImage:@"GreenButton.png"
selectedImage:@"WhiteButton.png"
disabledImage:nil
target:self
selector:@selector(changeToGreen)];
CCMenu * coloursMenu = [CCMenu menuWithItems:redButton,greenButton,nil];
coloursMenu.position = CGPointZero;
redButton.position = ccp(size.width * 0.30f,size.height * 0.5f);
greenButton.position = ccp(size.width * 0.70f,size.height * 0.5f);
[self addChild:coloursMenu z:10];
}
return self;
}
-(void) changeToRed {
[[CCDirector sharedDirector] replaceScene:[RedTest node]];
}
-(void) changeToGreen {
[[CCDirector sharedDirector] replaceScene:[GreenTest node]];
}
@end
@implementation GreenTest
-(id) init
{
if( (self=[super init]) ) {
// ask director for the window size
CGSize size = [[CCDirector sharedDirector] winSize];
//Add a background sprite.
//******* These two lines for the sprite
//CCSprite * background = [CCSprite spriteWithFile:@"GreenBack.png"];
//background.position = ccp(size.width * 0.5f,size.height * 0.5f);
//******* These two lines for the tilemap.
CCTMXTiledMap *background = [CCTMXTiledMap tiledMapWithTMXFile:@"GreenTileMap.tmx"];
background.position = ccp(0,0);
[self addChild:background z:0];
//Add a simple two button menu
CCMenuItem *yellowButton = [CCMenuItemImage
itemWithNormalImage:@"YellowButton.png"
selectedImage:@"WhiteButton.png"
disabledImage:nil
target:self
selector:@selector(changeToYellow)];
CCMenuItem *redButton = [CCMenuItemImage
itemWithNormalImage:@"RedButton.png"
selectedImage:@"WhiteButton.png"
disabledImage:nil
target:self
selector:@selector(changeToRed)];
CCMenu * coloursMenu = [CCMenu menuWithItems:yellowButton,redButton,nil];
coloursMenu.position = CGPointZero;
yellowButton.position = ccp(size.width * 0.30f,size.height * 0.5f);
redButton.position = ccp(size.width * 0.70f,size.height * 0.5f);
[self addChild:coloursMenu z:10];
}
return self;
}
-(void) changeToYellow {
[[CCDirector sharedDirector] replaceScene:[YellowTest node]];
}
-(void) changeToRed {
[[CCDirector sharedDirector] replaceScene:[RedTest node]];
}
@end