====== autorelease pools and release/retain ====== ===== Summary of Memory Management Rules ===== //(taken from "Programming in Objective-C")// * Releasing an object can free up its memory, which can be a concern if you're creating many objects during the execution of a program. A good rule is to release objects you've created or retained when you're done with them. * Sending a release message does not necessarily destroy an object. When an object's reference count is decremented to 0, the object is destroyed. The system does this by sending the dealloc message to the object to free its memory. * The autorelease pool provides for the automatic release of objects when the pool itself is released. The system does this by sending a release message to each object in the pool for each time it was autoreleased. Each object in the autorelease pool whose reference count goes down to 0 is sent a dealloc message to destroy the object. * If you no longer need an object fro within a method but need to return it, send it an autorelease message to mark it for later release. The autorelease message does not affect the reference count of the object. So, it enables the object to be used by the message sender but still be freed up later when the autorelease pool is released. * When your application terminates, all the memory taken by your objects is released, whether or not they were in the autorelease pool. * When you develop more sophisticated applications (such as Cocoa applications), autorelease pools can be created and destroyed during execution of the program (for Cocoa applications, that happens each time an event occurs). In such cases, if you want to ensure that your object survives automatic deallocation when the autorelease pool itself is released, you need to explicitly retain it. All objects that have a reference count greater than the number of autorelease messages they have been sent will survive the release of the pool. * If you directly create an object using an alloc or copy method (or with an allocWithZone:, copyWithZone:, or mutableCopy method), you are responsible for releasing it. For each time you retain an object, you should release or autorelease that object. * You don't have to worry about releasing objects that are returned by methods other than those noted in the previous rule. It's not your responsibility; those objects should have been autoreleased by those methods. That's why you needed to create the autorelease pool in your program in the first place. Methods such as stringWithString: automatically add newly created string objects to the pool by sending them autorelease messages. If you don't have a pool set up, you get a message that you tried to autorelease an object without having a pool in place. ===== autorelease pools ===== * in general, if you use the [ [object alloc] init] method of creating an object in memory, it is up to you to release it * if you use any other method to create the object, such as a class method (+), it is generally configured to be autoreleased * you can have multiple autorelease pools, including nested pools * cocoa gives you an autorelease pool for every program, but a foundation only program does not * it is generally good practice to use an autorelease pool in each method that needs one * make sure to distinguish that you are actually creating objects, rather than simply getting a reference to an object in a particular method * example: ... NSAutoreleasePool *aPool = [[NSAutoreleasePool alloc] init]; NSArray *filenames = [fm directoryContentsAtPath:path]; NSMutableArray *fullFilenames = [[NSMutableArray alloc] initWithCapacity:[filenames count]]; int i; for(i=0; i<[filenames count]; i++){ NSString *fullPath = [NSString stringWithFormat:@"%@/%@", path, [filenames objectAtIndex:i]]; [fullFilenames addObject:fullPath]; // fullPath is 2, and will be released to 1 after removeAllObjects, // then autoreleased to 0 if not retained elsewhere } [gridView createGridItemViews:fullFilenames]; [fullFilenames removeAllObjects]; [fullFilenames release]; // the following method call releases the "filenames" array, and the "fullPath" objects [aPool release]; ... ===== release/retain and retainCount ===== * objects have a retainCount, and when it reaches zero the object is deallocated from memory * to find the retainCount you send the message to the object: (int)[object retainCount] * to increment the retainCount, you send the message: [object retain] * to decrement the retainCount, you send the message: [object release] ===== Tips ===== * adding an object to a mutable array increases the retain count by 1 * removing an object from a mutable array decreases the retain count by 1 * adding a view to another view (subview/superview) increases the retain count by 1 * removing or replacing a subview with another view decreases the retain count by 1 * if you need to keep an object around, you may need to use [object retain] before some of the methods that decrement the retain count