title: EXC_BAD_ACCESS - How is this code causing a leak? Traced via malloc_history & NSZombieEnabled
body: <p><strong>UPDATE</strong> (at bottom): <em>Added entire viewWillAppear: method implementation to show how the three UIViewControllers are allocated / deallocated into the UIScrollView.</em></p>
  
  <p>I have a root ViewController which contains a <code>UIScrollView</code>. This <code>UIScrollView</code> itself contains 3 different <code>UIViewController</code>s (setup as <code>NSFetchedResultControllerDelegate</code>s for separate <code>UITableView</code>s.)</p>
  
  <p>I need to <strong>reload</strong> the root ViewController's <code>UIScrollView</code> at one point when we come back to the view so I do this at the beginning of:</p>
  
  <pre><code>-(void) viewWillAppear:(BOOL)animated {
   [dataViewScroller.subviews 
                   makeObjectsPerformSelector:@selector(removeFromSuperview)];
   .......
   // and we proceed to re-load the 3 UIViewControllers into the UIScrollView.
   // From testing this all seems to work fine.
   // The **problem** is that that as soon as this method ends - I get an
   // EXC_BAD_ACCESS error described above.
   // If the above line is removed, everythign works fine.
  }
  </code></pre>
  
  <p>Here is the viewDidLoad method for the each of the <code>UIViewControllers</code> loaded into the <code>UIScrollView</code> is as follows:</p>
  
  <pre><code> - (void)viewDidLoad {
  [super viewDidLoad];
  
  self.view.backgroundColor = [UIColor clearColor];
  self.expensesTableView.backgroundColor = [UIColor clearColor];
  
  self.theTableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
  self.theTableView.rowHeight = 44;
  
  UIView *containerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 280, 44)] autorelease];
  containerView.backgroundColor = [UIColor clearColor]; 
  
  // Setting up and aligning the label in the center of our view.
  UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 20)];   
  headerLabel.text = NSLocalizedString(self.headerText, @"");
  headerLabel.textColor = [UIColor blackColor];
  headerLabel.font = [UIFont boldSystemFontOfSize:16];
  headerLabel.backgroundColor = [UIColor clearColor];
  headerLabel.center = containerView.center;
  headerLabel.textAlignment = UITextAlignmentCenter;
  
  [containerView addSubview:headerLabel];
  
  // HOW IS THIS A LEAK? CAUSES EXC_BAD_ACCESS If Not commented out
  //NSLog(@"Test - %@", headerLabel);
  //[headerLabel release];
  
  [self.view addSubview:containerView];
  
  NSError *error;
  if (![[self fetchedResultsController] performFetch:&amp;error]) {
      // Update to handle the error appropriately.
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
      exit(-1);  // Fail
  }
  </code></pre>
  
  <p>}</p>
  
  <p>The code above has the line <code>headerLabel release]</code> commented out. With this out the program runs fine! If I enable the line <code>[headerLabel release]</code>, which I technically <strong>SHOULD</strong> have enabled since otherwise it's a LEAK, GDB then reports the following:</p>
  
  <pre><code> MyAppTest[11110:207] *** -[CFString release]: message sent to deallocated instance 0x5d66b60
  (gdb)
  
  This is the output from malloc_history trace using the above memory address:
  
  Identifier:      MyAppTest
  Version:         ??? (???)
  Code Type:       X86 (Native)
  Parent Process:  gdb-i386-apple-darwin [10116]
  
  Date/Time:       2011-03-15 03:14:47.855 -0400
  OS Version:      Mac OS X 10.6.6 (10J567)
  Report Version:  6
  
  ALLOC 0x5996770-0x599678f [size=32]: thread_a037a540 |start | main | UIApplicationMain | -[UIApplication _run] | CFRunLoopRunInMode | CFRunLoopRunSpecific | __CFRunLoopRun | __CFRunLoopDoSource1 | __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ | PurpleEventCallback | _UIApplicationHandleEvent | -[UIApplication sendEvent:] | -[UIApplication handleEvent:withNewEvent:] | -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] | -[UIApplication _reportAppLaunchFinished] | CA::Transaction::commit() | CA::Context::commit_transaction(CA::Transaction*) | CALayerLayoutIfNeeded | -[CALayer layoutSublayers] | -[UILayoutContainerView layoutSubviews] | -[UINavigationController _startDeferredTransitionIfNeeded] | -[UINavigationController _startTransition:fromViewController:toViewController:] | -[AccountViewController viewWillAppear:] | -[NSManagedObjectContext executeFetchRequest:error:] | -[NSPersistentStoreCoordinator executeRequest:withContext:error:] | -[NSSQLCore executeRequest:withContext:error:] | -[NSSQLCore objectsForFetchRequest:inContext:] | -[NSSQLCore newRowsForFetchPlan:] | -[NSSQLCore _newRowsForFetchPlan:selectedBy:withArgument:] | -[NSSQLCore _prepareResultsFromResultSet:usingFetchPlan:withMatchingRows:] | CFStringCreateWithCString | __CFStringCreateImmutableFunnel3 | _CFRuntimeCreateInstance | malloc_zone_malloc 
  </code></pre>
  
  <p>Pulling my hair out because there is absolutely ZERO messages or calls made to <code>headerLabel</code> after I <strong>release</strong> it. Anyone have any suggestions? please??</p>
  
  <p><strong>---- UPDATE</strong></p>
  
  <pre><code>- (void) viewWillAppear:(BOOL)animated {
  
  [super viewWillAppear:animated];
  
  [dataViewScroller.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
  
  [self.myTableViewControllers removeAllObjects];
  self.myTableViewControllers = nil;
  
  // All database modifcations should dynamically reload when the view reappears
  
  /* RE-OBTAIN CATEGORIES */
  NSManagedObjectContext *context = [myAppTestAppDelegate managedObjectContext];
  
  NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
  NSEntityDescription *entity = [NSEntityDescription entityForName:@"MyObjectType" inManagedObjectContext:context];
  [fetchRequest setEntity:entity];
  
  NSError *errorInRequest = nil;
  NSArray *results = [context executeFetchRequest:fetchRequest error:&amp;errorInRequest];
  
  if(errorInRequest)
  {
      NSLog(@"Unresolved error %@, %@", errorInRequest, [errorInRequest userInfo]);
      abort();
  }
  
  [fetchRequest release];
  
  kNumberOfPages = [results count];
  
  dataViewPageControl.numberOfPages = kNumberOfPages;
      dataViewPageControl.currentPage = 0;
  dataViewScroller.contentSize = CGSizeMake(dataViewScroller.frame.size.width * kNumberOfPages, dataViewScroller.frame.size.height);
  
  // the view controllers are created lazily
  // in the meantime, load the array with placeholders which will be replaced on demand
  NSMutableArray *controllers = [[NSMutableArray alloc] init];
  for (unsigned i = 0; i &lt; kNumberOfPages; i++) {
      [controllers addObject:[NSNull null]];
  }
  
  self.myTableViewControllers = controllers;
  [controllers release];
  
  int index = 0;
  
  for (NSManagedObject *type in results) {
      [self loadScrollViewWithPage:index withIdentifier:[type valueForKey:@"name"]];
      index++;
  }
  
  }
  
  - (void)loadScrollViewWithPage:(int)page withIdentifier:(NSString *)ident {
  
  if (page &lt; 0) return;
  if (page &gt;= kNumberOfPages) return;
  
  MyTableListViewController *controller = [myTableViewControllers objectAtIndex:page];
  
  if ((NSNull *)controller == [NSNull null]) {
      controller = [[MyTableListViewController alloc] initWithPageNumber:page withHeader:ident];
      controller.managedObjectContext = [myAppTestAppDelegate managedObjectContext];
      [myTableViewControllers replaceObjectAtIndex:page withObject:controller];
      [controller release];
  }
  if (nil == controller.view.superview) {
      CGRect frame = dataViewScroller.frame;
      frame.origin.x = frame.size.width * page;
      frame.origin.y = 0;
      controller.view.frame = frame;
      [dataViewScroller addSubview:controller.view];
  }
  }
  </code></pre>
  
  <p>So as you can see, they are always loaded dynamically when the Root ViewController loads. This is because the user can go to an <em>Account Settings</em> type admin page and add additional categories to their setup. When returning to the Root View the NEW / OR DELETED categories must be rendered in the scroll view. If they had 3 Cateogories (ie. 3 TableViewControllers) initially and went to the admin page and created a new one, when returning the the UIScrollView should reload with all 4 categories (4 dynamically created TableViewControllers.) Does this make sense?</p>