<p>If I spawn a new thread, and then within it I push a new controller onto my UINavigationController, using code like this...</p>

<p>(a) not working</p>

<pre><code>-(void)myCallbackInThread
{
    // move on...
    UIApplication* app = [UIApplication sharedApplication];
    [app changeView];
}
</code></pre>

<p>then I find that the view appears, but does not respond to user input.</p>

<p>If I change the code like this</p>

<p>(b) working</p>

<pre><code>-(void)myCallbackInThread
{
    // move on...
    UIApplication* app = [UIApplication sharedApplication];
    [app performSelectorOnMainThread:@selector(moveToMain) withObject:nil waitUntilDone:FALSE];
}
</code></pre>

<p>Then everything works just fine.</p>

<p>Any hints as to why?</p>

Just found this in the iPhone threading docs
If your application has a graphical
  user interface, it is recommended that
  you receive user-related events and
  initiate interface updates from your
  application’s main thread. This
  approach helps avoid synchronization
  issues associated with handling user
  events and drawing window content.
  Some frameworks, such as Cocoa,
  generally require this behavior, but
  it also has the advantage of
  simplifying the logic for managing
  your user interface.
I still don't see what would actually cause something to display but not be able to receive user input, but I'll follow that guideline in future.