title: “Normal” UIButton causing obj_stack_overflow or EXC_BAD_ACCESS exception
body: <p>It sure looks innocuous enough. In my App Delegate, I check <strong>NSUserDefaults</strong> for a flag to show tips at startup. If it’s set then, at the end of <code>applicationDidFinishLaunching:</code>, I do this:</p>
  
  <pre><code>TipsViewController *vc = [[TipsViewController alloc]
    initWithNibName:@“TipsView" bundle:nil];
  [window addSubview:vc.view];
  [vc release];
  </code></pre>
  
  <p>The idea is to show this view temporarily. (Note that it’s not a modal VC. No Navigation Controller at this point, plus there’s no navigation bar in this view anyway.)</p>
  
  <p>Once this view is dismissed, we’ll add our pre-empted <strong>UITabBarController</strong>’s view to the window and transition over to it, then remove the tip view from the main window. I haven’t made it to the view dismissal point yet because, well, keep reading.</p>
  
  <p>My TipsView’s VC is wired up more or less like so:</p>
  
  <pre><code>UIView -&gt; view -&gt; File’s Owner (TipsViewController)
    UIImageView -&gt; background image
    UIView -&gt; tipView -&gt; File’s Owner
      UIImageView -&gt; background image
      UIScrollView
        UILabel (tip text)
      UIButton -&gt; touch-up-inside -&gt; -(IBAction)button1:
      UIButton -&gt; touch-up-inside -&gt; -(IBAction)button2:
      UIButton -&gt; touch-up-inside -&gt; -(IBAction)button3:
  </code></pre>
  
  <p>The source contains declarations and definitions for all three <strong>IBAction</strong> calls. Right now two of them do nothing. The third one changes the tip <code>text</code>, resizes it to fit, and adjusts the scroll view’s <code>contentSize</code> to match.</p>
  
  <p>When I run the app, the <strong>TipsViewController</strong> view shows up just fine. I can even scroll through the tip text. However, when I trigger a touch-up-inside on any <strong>UIButton</strong>, Xcode starts to plant me in the source (where I’ve placed a breakpoint at each <strong>IBAction</strong>) … and then bails out with either a <code>EXC_BAD_ACCESS</code> or <code>obj_stack_overflow</code>.</p>
  
  <p>I have compared this with other parts of the app where I have a VC, a view, and buttons. It is identical in every way except that, in this case, <em>I’ve added a VC’s view as a subview of the app’s window instead of pushing the VC onto a navigation controller</em>. Moreover, the <strong>View Controller Programming Guide for iPhone OS</strong> docs say this is fair game:</p>
  
  <blockquote>
    <p>If you use a single view controller in
    your application, you add its view to
    a window instead of adding the view
    controller to a tab bar or navigation
    controller.</p>
  </blockquote>
  
  <p>True, I <em>do</em> have a <strong>UITabBarController</strong> waiting in the wings, and it has tabs with <strong>UINavigationControllers</strong> (and other VCs) in it. However, if the tip view is being shown, the tab bar controller’s view has <em>not</em> yet been added to the window. The intent is to swap it in after we’re done showing tips. In other words, for all intents and purposes, we’re temporarily acting like we have a single VC in play. Afterward, we switch to the tab bar and tear down the tip VC.</p>
  
  <p>Perhaps I’m doing something subtly wrong? Is there a better way? (“There’s got to be a better way!”)</p>
  
  <p>Sample stack trace:</p>
  
  <pre><code>#0  0x992b6f52 in objc_exception_throw
  #1  0x302d6ffb in -[NSObject doesNotRecognizeSelector:]
  #2  0x3026e056 in ___forwarding___
  #3  0x3024a0a2 in __forwarding_prep_0___
  #4  0x308f79d1 in -[UIApplication sendAction:to:from:forEvent:]
  #5  0x309598b1 in -[UIControl sendAction:to:forEvent:]
  #6  0x3095bad2 in -[UIControl(Internal) _sendActionsForEvents:withEvent:]
  #7  0x3095a81e in -[UIControl touchesEnded:withEvent:]
  #8  0x30910fdf in -[UIWindow _sendTouchesForEvent:]
  #9  0x308faecb in -[UIApplication sendEvent:]
  #10 0x309013e1 in _UIApplicationHandleEvent
  #11 0x32046375 in PurpleEventCallback
  #12 0x30245560 in CFRunLoopRunSpecific
  #13 0x30244628 in CFRunLoopRunInMode
  #14 0x32044c31 in GSEventRunModal
  #15 0x32044cf6 in GSEventRun
  #16 0x309021ee in UIApplicationMain
  #17 0x00002888 in main at main.m:14
  </code></pre>
  
  <p>As you can see from the trace, we end up at <code>doesNotRecognizeSelector:</code> … except I can clearly see the methods in my tip VC source. Plus, they’re all wired up. (No multiple wirings or anything like that in IB. Everything looks good there, down to the File’s Owner relationships.)</p>
  
  <p>Clues welcome/appreciated!</p>