I read up on this error and it's supposedly thrown when I access a variable or object that has been released. But I'm not sure how to fix this error! I'm using Cocos2D to program a basic SpriteController that keeps track of all my Sprites and sends them a touchBegan: to keep track of touches.
I made a Basic HelloWorldScene.m that initializes like this:
if (allMySprites == nil) {
//touched = false;
} else {
for (CCSprite *sprite in allMySprites) {
if([sprite respondsToSelector:@selector(touchBegan: )]) {
touched = [sprite touchBegan: cgp];
}
}
}
return touched;
}
The program displays the 2 red1.gif boxes on the screen during initialization fine. And after debugging around, I figured that the flow of the program does enter the TouchBegan and is passed to the SpriteController. However, as soon as I begin looping through allMySprites, I get the EXC_BAD_ACCESS error. After playing around with it, I determined that I simply can't access any of the objects in allMySprites beyond initialization. So even if I added a [allMySprites lastObject] directly in the scene, it'd throw the error. Why can't I access the objects in allMySprites? They don't seem to be released by the time I want to use them, but it just doesn't let me touch them.
You might get this error if the array that "allMySprites" points to is autoreleased and not retained. How do you create that array?
Any time someone says "my object works when I create it, but not later" it's usually an autorelease problem.
Sorry, forgot to point that out. When I add a sprite to the allMySprites array, it automatically checks to see if allMySprites has been created, and if not, calls:
allMySprites = [NSMutableArray array];
to actually create the array. Though I'm new at this kind of programming, I recall that any object not created by me (not using alloc, new, copy) is automatically handled by the system. By creating allMySprites using Apple's API for NSMutableArray, shouldn't it automatically be handled, autoreleased/retained for me?
Though I'm new at this kind of programming, I recall that any object not created by me (not using alloc, new, copy) is automatically handled by the system. By creating allMySprites using Apple's API for NSMutableArray, shouldn't it automatically be handled, autoreleased/retained for me?
No, "autoreleased" doesn't mean that the memory is managed for you; it means that the object will be released at the end of the current event, and possibly destroyed unless you retain it in some way. You will have to learn the retain/release rules to make a working program.
No, "autoreleased" doesn't mean that the memory is managed for you; it means that the object will be released at the end of the current event, and possibly destroyed unless you retain it in some way. You will have to learn the retain/release rules to make a working program.
Now allMySprites will stick around until you release it.
Wait, doesn't autorelease add the object into the pool to be drained? If what you're saying is true, then it makes sense. Do you know how often or when Cocos2D drains the AutoReleasePool? In my knowledge, I know that the array returned with [NSMutableArray array] is autoreleased by Apple, but I would think that the pool is drained at the end of the program (when the scene switches or the program is turned off). Am I wrong to assume this?
As smasher said, the pool is drained after each event. Or at least, that is what you should assume. If you create an autoreleased object within a method, you can assume that it will be destroyed after the method is executed.
If the routine waited until the end of the programme/until you close the app, there would be no "release". At least not effectively as you'd hang on to all objects until the end of the app. That's what you want to avoid! Get rid of objects as soon as you can (read: as soon as you don't need them anymore) in order to free memory again so you can use it for something else.
Cheers,
Bob
__________________ We are God’s middle children, according to Tyler Durden, with no special place in history and no special attention.
As smasher said, the pool is drained after each event. Or at least, that is what you should assume. If you create an autoreleased object within a method, you can assume that it will be destroyed after the method is executed.
If the routine waited until the end of the programme/until you close the app, there would be no "release". At least not effectively as you'd hang on to all objects until the end of the app. That's what you want to avoid! Get rid of objects as soon as you can (read: as soon as you don't need them anymore) in order to free memory again so you can use it for something else.
Cheers,
Bob
Alright, that makes sense. That's knowledge I didn't know. So the pool is drained after every event? That clarifies things. I'll fix it up and see if it works now!