Objective C Memory Management

I found two concise but complete references online:
http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/MemoryMgmt/Articles/MemoryMgmt.html
http://interfacelab.com/objective-c-memory-management-for-lazy-people/
http://www.raywenderlich.com/2657/memory-management-in-objective-c-tutorial

I will summarize them here to reinforce my understanding:

  1. If you do alloc + init or new (which is basically just a shortcut for alloc + init), you must subsequently call release.
  2. After you call release, you should set the var name to nil. So: [someVar release], and then someVar = nil; This is considered good practice (at least by Ray Wenderlich), because sending message to a nil var does nothing, while sending message to a deallocated var causes EXC_BAD_ACCESS.
  3. If you get a var from framework methods, then there's this convention:
    • If the method name begins with init or copy, the object returned will have a retain count of 1, and no autorelease pending. In other words, you own that object and have to release it when you’re done.
    • If the method name begins with anything else, the object returned will have a retain count of 1, and an autorelease pending. In other words, you can use the object right now, but if you want to use it later you have to retain the object.
  4. More about property, here's a snapshot of The Elements sample code:

    // Set up the portraitWindow and content view
    UIWindow *localPortraitWindow;
    localPortraitWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.portraitWindow = localPortraitWindow;

    // the localPortraitWindow data is now retained by the application delegate
    // so we can release the local variable
    [localPortraitWindow release];

    Lesson: when you retain a property, you increment its ref count. So you need to release accordingly.
  5. Do this:
    -(NSImage *)getAnImage {

    return [[[NSImage alloc] initWithContentsOfFile:@"/tmp/youownthis.jpg"] autorelease];

    }
    Instead of this:
    -(NSImage *)getAnImage {

    return [[NSImage alloc] initWithContentsOfFile:@"/tmp/youownthis.jpg"];

    }
    The caller will then have to retain the returned object, and subsequently release it.
Now, on the topic of XCode profile -> leaks tool. I made a curious discovery. I build a skeleton table view app, just a navigation controller and a root view controller. Without any string occupying any table cell. And then I ran the profiler with leaks template. I randomly clicked on the table, and I pulled the table up and release it and pull it down and release it and I did it multiple times. And it red bold lines showed up! UIKit framework is leaking memory!

Even the official The Elements sample code from Apple website is leaking memory when tested this way.

0 komentar:

Posting Komentar