3

I have an ios app that uses cocos2d v1.1.0-beta2b, and encountered a very strange condition with emitters' auto removal.

My question is:

Is there any way that an infinite duration CCParticleSystemQuad, with an autoRemoveOnFinished set to YES, will be removed before I call stopSystem?

Here is some additional info:

I initialize the emitter as follows:

NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
emitter = [[[CCParticleSystemQuad alloc]
                                    initWithDictionary:dict] autorelease];
emitter.duration = -1.0f;
[emitter setAutoRemoveOnFinish:YES];
[self addChild:emitter z:10];

Then, it is of course added as a child and everything works perfectly. As suggested in many places, in order to remove it I call:

[emitter stopSystem]; 

After that, when all the particles are gone the emitter is removed as expected.

So far all is well.

However, I've encountered several crash reports that indicate that the emitter is released prematurely, and then my app crashes on the stopSystem line (as emitter is already released). I got several feedbacks that indicate that it sometimes happen when the device is locked/unlocked during the emitter activity, though for me it works and these crashes are rare. I haven't been able to reproduce the circumstances under which it happens, so I ask you guys again:

Is there any way that an infinite duration CCParticleSystemQuad, with an autoRemoveOnFinished set to YES, will be removed before I call stopSystem?

am1987
  • 347
  • 3
  • 13

1 Answers1

-1

Looks like you have a zombie infestation.

Zombie is caused by a dangling pointer: an object to which it was pointing was already released, but pointer continues to point to that location. When you try to call any method of that object, you get a crash.

emitter = [[[CCParticleSystemQuad alloc]
                                initWithDictionary:dict] autorelease];

your emitter points to autoreleased object. Looks like it "continues" to exist while autorelease pool is not being drained;

it sometimes happen when the device is locked/unlocked during the emitter activity,

and this sounds like lock/unlock triggers autorelease pool draining, and your emitter turns into zombie.

You can debug it with NSZombieEnabled. With NSZombieEnabled objects don't get deallocated immediately when they should, but turn into NSZombie objects. Any attempt to call method of NSZombie will give you a message in console: "message sent to deallocated instance".

Community
  • 1
  • 1
Kreiri
  • 7,840
  • 5
  • 30
  • 36
  • 1
    Correct me if I'm wrong, but when I add the emitter as a child in cocos2d using addChild, the object shouldn't be autoreleased... I'll edit my post to make it clearer. – am1987 Jul 13 '13 at 13:37