title: Why are subviews of an NSView not sent a release message when a Cocoa application terminates?
body: <p><strong>The short version:</strong></p>
  
  <ol>
  <li> Why are the subviews of NSView objects not sent a <code>release</code> message when a Cocoa application terminates?
  <li> Is there a way to override this behaviour?
  </ol>
  
  <p><strong>An example:</strong><br>
  The <code>MyView</code> class shown below is nothing more than an <code>NSView</code> subclass that reports to the console when it is created and destroyed. I have tested it out and found it to work properly. However, when I use it as shown in the next code snippet from my application delegate, I see something unexpected (see sample output).</p>
  
  <pre><code>// MyView:
  
  @interface MyView : NSView { }
  @end
  
  @implementation MyView
  
  - (id)initWithFrame:(NSRect)frameRect
  {
      if ((self = [super initWithFrame:frameRect]) == nil) { return nil; }
      NSLog(@"init %@", self);
      return self;
  }
  
  - (void)dealloc
  {
      NSLog(@"dealloc %@", self);
      [super dealloc];
  }
  
  @end
  </code></pre>
  
  <p><code></code></p>
  
  <pre><code>// Application delegate:
  
  - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
  {
      NSLog(@"begin");
  
      parentView = [[MyView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)];
  
      MyView * myView = [[MyView alloc] initWithFrame:NSMakeRect(10, 10, 80, 80)];
      [parentView addSubview:myView];
      [myView release];
  
      NSLog(@"run");
  }
  
  - (void)applicationWillTerminate:(NSNotification *)aNotification
  {
      NSLog(@"quit");
      [parentView release];
      NSLog(@"end.");
  }
  </code></pre>
  
  <p>This application produces the following output:</p>
  
  <blockquote>
    <p>begin<br>
    init <code>&lt;</code>MyView: 0x10013f840<code>&gt;</code><br>
    init <code>&lt;</code>MyView: 0x10261b620<code>&gt;</code><br>
    run<br>
    quit<br>
    dealloc <code>&lt;</code>MyView: 0x10013f840<code>&gt;</code><br>
    end.</p>
  </blockquote>
  
  <p><strong>The problem:</strong><br>
  I can clearly see that the first view object is being released when the application quits, and I'm certain (tested and verified) that <code>NSView</code> objects automatically release their subviews when they themselves are released. However, it appears that during application termination those subviews are not being released.</p>
  
  <p><strong>The long version: (AKA why on earth would anyone care? :)</strong><br>
  Let me start by saying that I am familiar with the way memory is freed by a running application when it quits. I know that my subviews will be properly disposed of, even if they are never sent a <code>release</code> message, so I'm not worried about this being a leak. In fact, I'm pretty sure (but not 100% certain) that the answer to my question #1 is: "Because releasing subviews is unnecessary when the application is about to terminate."</p>
  
  <p>I use some simple hand-rolled code to do memory tracking while my application is running in debug mode. I make a calls to a <code>Trace_Init()</code> and <code>Trace_Dealloc()</code> method in the <code>init</code> and <code>dealloc</code> methods of all of my custom classes, and I use the <code>atexit()</code> function to report any unreleased objects after the Cocoa portion of my application has finished. I find this to be much simpler than running Apple's memory leak performance tool on a regular basis. If I cause a memory leak while running, I'll know about it as soon as my application quits.</p>
  
  <p>However, the lack of a <code>dealloc</code> call during termination means that any of my custom <code>NSView</code> subclasses that are used as subviews show up as memory leaks when I quit the application. Thus the reason for my question #2. I would like to have Cocoa release everything during termination so that my memory tracking is able to wrap up properly. Naturally, I would only override the default behaviour in debug mode. My released app has none of the memory tracking code enabled, and should be able to quit itself as efficiently as normal.</p>
  
  <p><strong>That's it!</strong> (phew) If you made it this far, thank you for taking the time to read it all.</p>