Greetings,
I have read a fair amount about memory management in Objective-C, so I know the mantra of the 3 magical words (new, alloc, copy)… However, the thing that often causes me confusion is when exactly is it appropriate to retain an object?
Take for example this code (for sake of clarity, this is pseudo code, you can assume params and variables are passed in as needed):
<INSIDE OF CLASS_A)
-(CCAnimation *) createAnimation
{
NSMutableArray *frames = [NSMutableArray array];
CCSpriteFrame *frame=nil;
CCTexture2D *texture = [[CCTextureCache sharedTextureCache] addImage:<some param>];
for (int i=0; i<numFrames; i++) // Add frames in order
{
frame = [CCSpriteFrame frameWithTexture:<some params>];
[frames addObject:frame];
}
CCAnimation *animation = [CCAnimation animationWithName:animationName delay:0.2f frames:frames];
return animation; // NOTE: I am assuming I don't need to autorelease animation as I am passing it back to caller
}
Do I have to retain any of this at this point? Specifically, does frame need to be retained (or does adding it to frames:addObject handle this). Also, does frames need to be retained, or is that handled by animation object (as it is a param of animationWithName)?
To take this one step further, lets assume I call the above function (from this method in another class) as follows:
(INSIDE OF CLASS_B)
-(CCSprite *) addSpecificSprite
{
CCAnimation *animationSeq =
[INSTANCE_OF_CLASSA createAnimationSequence:<params>];
CCSprite *mySprite = [CCSprite spriteWithFile:<params>];
[mySprite runAction:[CCRepeatForever actionWithAction: [CCAnimate actionWithAnimation: animationSeq <params>] ]];
return mySprite; // NOTE: I am assuming I don't need to autorelease mySprite as I am passing it back to caller
}
Again, do I need to retain anything at this point? animationSeq is inside the call to mySprite:runWithAnimation…so does that make sure to retain it for as long as needed?
Lastly, say the above method is then called from an instance of a 3rd class:
INSIDE CLASS_C (extends CCLayer)
-(void) init
{
[…other code…]
CCSprite *characterSprite = [INSTANCE CLASS_B addSpecificSprite];
[self addChild:characterSprite <params>];
[…other code…]
}
Same question, does characterSprite need to be retained? or does using addChild handle retaining it as needed?
Like I said, I understand when I need to specifically handle cleanup (delete, release, etc), but the issue that keeps me wondering is how do I know which methods that I pass an object to will handle the retain/release issues for that object?
Sorry for the complexity of the code sample, I tried to distill it down to the points of interest, being that of whether passing a object into the constructor (or into methods addObject, runAction, animateWithName, addchild, etc) of another object keeps me from having to worry about retention issues.
Also, should I be doing any autoreleasing in the above example?
Any help is greatly appreciated.
Q
PS(Note: I am not asking about releasing these since I understand that I only need to do that if I specifically retain them.)
PSS(I specifically made the variables for animation, mySprite, and myCharacter local (method) variables to demonstrate that for this example, I am NOT using them outside of the codeblocks in which they were created (except as return values). I realize that if I wanted to use them outside their respective codeblocks I would need to store them in member variables and retain/release them).