请耐心等待我发布长码。 我是CCSprite的子类:
@interface Character : CCSprite {
}
-(id) initWithTexture:(CCTexture2D*)texture rect:(CGRect)rect;
@end
@implementation Character
-(id) initWithTexture:(CCTexture2D*)texture rect:(CGRect)rect
{
NSLog(@"in initWithTexture");
if( (self=[super initWithTexture:texture rect:rect]))
{
}
return self;
}
-(void) dealloc
{
NSLog(@"character dealloced");
[super dealloc];
}
@end
问题#1:这是对的吗?
我有一个包含这个精灵的图层作为类变量,还有另一个CCSprite。
Character *characterSprite;
CCSprite *burpSprite;
该图层还有两个CCAnimation对象:
CCAnimation *burpAnim;
CCAnimation *burpParticlesAnim;
在这堂课中,我有两种方法: - (void)loadBurpAnimation; - (void)unloadBurpAnimation;
-(void) loadBurpAnimation {
NSString* burpFile;
NSString* burpFilePVR;
NSString* burpParticlesFile;
NSString* burpParticlesFilePVR;
burpFile = @"latestBurp1-1.plist";
burpFilePVR = @"latestBurp1-1.pvr.ccz";
burpParticlesFile = @"burpParticles1-1.plist";
burpParticlesFilePVR = @"burpParticles1-1.png";
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:burpFile texture:[[CCTextureCache sharedTextureCache] addImage:burpFilePVR]];
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:burpParticlesFile texture:[[CCTextureCache sharedTextureCache] addImage:burpParticlesFilePVR]];
NSMutableArray *burpFrames = [NSMutableArray array];
for(int i = 231; i <= 268; ++i) {
[burpFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"burp.%d.png", i]]];
}
burpAnim = [[CCAnimation alloc] initWithFrames:burpFrames delay:0.04f];
[burpFrames removeAllObjects];
//Burp Particles
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:burpParticlesFile];
NSMutableArray *burpParticlesFrames = [NSMutableArray array];
for(int i = 3; i <= 37; ++i) {
[burpParticlesFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"Burp_%05d.png", i]]];
}
burpParticlesAnim = [[CCAnimation alloc] initWithFrames:burpParticlesFrames delay:0.04f];
[burpParticlesFrames removeAllObjects];
}
-(void) unloadBurpAnimation {
[burpAnim release];
[burpParticlesAnim release];
}
我必须在线程中加载burp动画并在主线程上调用一个方法来播放它,如下所示:
-(void) loadAnimation {
NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
[dictLock lock];
if( [EAGLContext setCurrentContext:auxEAGLcontext] ) {
[self loadBurpAnimation];
[self performSelectorOnMainThread:@selector(burpAnimation) withObject:nil waitUntilDone:NO];
} else {
CCLOG(@"cocos2d: TetureCache: EAGLContext error");
}
[dictLock unlock];
[autoreleasepool drain];
}
我知道有一种方法可以单独加载动画“asynchAddImage”,但这不是关注点。
-(void) burpAnimation {
CCAction *burpAction = [CCSequence actions:
[CCAnimate actionWithAnimation:burpAnim restoreOriginalFrame:NO],
[CCCallFunc actionWithTarget:self selector:@selector(animationDone)],nil];
CGSize winSize = [CCDirector sharedDirector].winSize;
characterSprite = [[Character alloc] initWithSpriteFrameName:@"burp.231.png"];
characterSprite.position = ccp(winSize.width/2, winSize.height/2);
[characterSprite setScale:1.5];
CCAction *particlesAction = [CCSequence actions:
[CCAnimate actionWithAnimation:burpParticlesAnim restoreOriginalFrame:NO],
nil];
burpSprite = [[CCSprite alloc] initWithSpriteFrameName:@"Burp_00003.png"];
burpSprite.position = ccp(winSize.width/2-50, winSize.height/2-80);
[self addChild:characterSprite];
[characterSprite release];
[self addChild:burpSprite];
[burpSprite release];
[characterSprite runAction:burpAction];
[burpSprite runAction:particlesAction];
}
我面临的真正问题是在动画后调用CCCallFunc选择器:
- (void)animationDone {
//Here characterSprite retain count is 2
NSLog(@"B4 stop char rc %d", [characterSprite retainCount]);
[characterSprite stopAllActions];
//Here characterSprite retain count is still 2
NSLog(@"B4 stop char rc %d", [characterSprite retainCount]);
[self removeChild:characterSprite cleanup:YES];
>>> //Here characterSprite retain count is 1 WHY?
>>> NSLog(@"char rc %d", [characterSprite retainCount]);
//Here burpSprite retain count is 2
NSLog(@"particles rc %d", [burpSprite retainCount]);
[burpSprite stopAllActions];
//Here burp retain count is 1
NSLog(@"particles rc %d", [burpSprite retainCount]);
[self removeChild:burpSprite cleanup:YES];
// releases the animation objects
[self unloadBurpAnimation];
//Here burpAnim retainCount = 1
NSLog(@"BURP ANIM rc = %d", [burpAnim retainCount]);
//Here burpParticlesAnim retainCount = 0 , crashes if print here obviously.
//NSLog(@"Particles ANIM rc = %d", [burpParticlesAnim retainCount]);
[[CCSpriteFrameCache sharedSpriteFrameCache] removeUnusedSpriteFrames];
[[CCTextureCache sharedTextureCache] removeUnusedTextures];
}
两个问题: 虽然我删除了characterSprite,但我的保留计数等于1。 虽然我已经发布了burpAnim但我的保留计数等于1,因为这个CCSpriteFrameCache无法删除spriteFrames,因此纹理也不会被删除。
这两个问题是否相互关联? 谢谢你们阅读本文,非常感谢任何帮助。
答案 0 :(得分:0)
两个问题:虽然我已经删除了 我保留了characterSprite 数等于一。虽然我有 发布了burpAnim我得到了它的保留 由于这个原因,计数等于1 CCSpriteFrameCache无法删除 spriteFrames,因此纹理是 也没有删除。
您的第一个问题是您正在呼叫retainCount
并认为返回的号码是有意义的。
对象的保留计数应始终视为delta。如果你通过保留某些东西来增加它,你必须通过释放或自动释放其他地方来减少它。哪里完全取决于你“拥有”对象的引用多长时间。
还有其他一些可疑的内容:
burpAnim = [[CCAnimation alloc] initWithFrames:burpFrames delay:0.04f];
[burpFrames removeAllObjects];
为什么在之前的for()循环中设置burpFrames
的内容,然后将其传递给CCAnimation
,然后立即removeAllObjects
?如果CCAnimation
没有复制数组,那么你只需从动画中清空它。由于数组是自动释放的,因此无需清空它。
同样适用于burpParticleFrames
。
在一个线程上锁定(dictLock
)然后调用主线程似乎很可疑;像一个生成死锁的好方法。如果主线程不应该锁定该线程,你是否有多个后台线程在运行?你的并发模型是什么?
请注意,[self removeChild:characterSprite cleanup:YES];
可能会释放characterSprite
,因为希望self
上的方法遵循正常的Cocoa约定。
这听起来像你有一些基本的保留/释放问题。 Read the guide然后使用Build and Analyze来解决任何问题。如果您的应用仍然崩溃,请使用Zombie检测来确定解除分配后的消息。