views:

627

answers:

2
#import <UIKit/UIKit.h>

int main(int argc, char *argv[]) {
    NSLog(@"new event...");
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, nil);
    [pool release];
    return retVal;
}

If that's the case, then the main() function would have to be called on every event, right? But I tried it, and the "new event..." log message comes just on app start. So I guess that there must be another autorelease pool in the main thread.

+1  A: 

No, this is the outermost function in your application, a regular C-style main().

Everything that the iPhone app does takes place in UIApplicationMain, including all the event handling.

Nick Brosnahan
+3  A: 

No. All Cocoa or CocoaTouch classes require the presence of an autorelease pool in order to not leak memory. Thus, an existing autorelease pool is required to call UIApplicationMain() in order to cover any (possibly) autoreleased objects that are instantiated in the context of UIApplicationMain(). This outer autorelease pool is, as you can see drained after return of UIApplicationMain, just before application exit. An inner (remember that autorelease pools can be nested and autoreleased objects are added to the newest/deepest pool) autorelease pool is created at the beginning of each iteration of the application's run loop and released at the end of the iteration. Thus, each iteration of the run loop gets is "own" autorelease pool. If processing an event might generate a lot of autoreleased memory (a bad idea on the iPhone, but quite common on OS X), you may want to create your own inner autorelease pools in the event handling code which can be released during processing of that event.

Barry Wark
What's the point of the outermost, 'main()' autorelease pool, since all application memory will be reclaimed by the OS on exit anyways? And I'm curious why Apple didn't simply include a top-level autorelease pool inside the implementation of UIApplicationMain().
Daniel Dickison
Thanks. Yeah, I'm wondering too... maybe there is some -autorelease'd stuff that happens beside the main run loop in UIApplicationMain()...
Thanks
An +initialize method is sent to classes before they receieve their first message. Unless writers of UIApplicationMain (or any user-supplied replacement) are very careful to instantiate an autorelease pool ANY other call to a Cocoa-derived class, this may cause a memory leak--those +initialize methods may autorelease objects. The safest plan is then to have an autorelease pool in place before calling any code that relies on Cocoa. UIApplicationMain may create its own autorelease pool anyways, of course.
Barry Wark
@Daniel There's no reason, except for being explicit and thorough that the pool needs to drained immediately before application exit.
Barry Wark
Barry, failing to have the outermost autorelease pool can’t cause a leak in the normal sense, since all memory is freed when main() returns anyway. however, classes may do things other than release memory in -dealloc, such as finish writing files or cleanly close network connections.
Ahruman
@Ahruman You are correct. I *think*, however that autoreleasing an object without an in-place autorelease pool generates at least an ugly log message--some would consider that a bug in production code. And I *think* that OS X will clean up open files and network sockets at process exit as well. I would assume iPhone OS will do similarly. Of course, I still think being explicit and properly releasing/freeing all resources is the correct behavior.
Barry Wark
Barry, that's right. If there no ARP around you get nice error logs and memory leaks. I've been reading that -dealloc may not always be called on exit, so -dealloc is the wrong place for freeing up ressources like file pointers, etc.
Thanks
@Swanzus Discussions about exit are somewhat irrelevant. -dealloc is the correct place to free resources in a reference counted (non GC) environment. In a garbage collected environment, the recommendation is that you expose a separate "clean up" method that is called `when you are done with the resources`. It's unfortunately quite difficult to determine this sometimes, but that's the recommendation. When an app exists, all relevant resources are cleaned up by the operating system.
Barry Wark