Background: Up until Xcode 4.2, new projects created using any of the templates would contain a MainWindow.xib and therefore pass nil as the fourth argument of UIApplicationMain(). Starting in Xcode 4.2 all the templates instantiate the application delegate by passing the class string as the fourth argument and do not build the application's window in a xib.
It is trivial to accomplish this setup in 4.2, and of course it works as expected: create xib setting File's Owner to UIApplication and wire up the delegate, specify it in Info.plist, nil fourth argument in main().
Question: Why is Apple encouraging instantiating the application delegate and building the UIWindow in code now instead of the "old way?" What are the benefits?
Considerations: I would expect this new template behavior if you elect to use storyboarding as a way to manage the UI, but if you uncheck "Use Storyboards" I would have expected the old pass-nil-and-use-MainWindow.xib template.
This question was asked in a roundabout way here, but the answers are a little thin on discussion.
You're asking why Apple is doing something? There can be no definitive answer, unless Apple has spoken out explicitly, which they have not done.
Personally I find the new approach considerably more elegant, transparent, and bulletproof. As you rightly say, in the old approach the main nib was loaded automatically by the runtime in response to the Info.plist setting, and everything else that happened was done through the nib, in particular the instantiation of the app delegate and the window and the associated wiring (the app delegate must be made the application delegate, the window must be made the app delegate's window), except that then we come back to the code in the app delegate for final presentation of the interface.
This was hard to understand; it took a great deal of verbiage for me to describe it in my book. It was also easy to break. The nib has to know the name of the app delegate class, so if you didn't like those funny long names that were created by default, you could easily mess everything up when you changed them.
Now, however, the app delegate is simply named App Delegate and is instantiated in code by UIApplicationMain(), as you rightly say; and everything else is also done in code as a direct follow-on: the app delegate is instantiated and didFinishLaunching is called, whereupon we create the window in code, assign it to our property in code, load the nib if there is one in code, set the window's rootViewController in code, and show the interface in code as before.
Thus the bootstrapping is directly exposed to view because it's all code. This makes it easier to understand and to modify without breaking anything. It's almost as if previously the template designer was just showing off as to how much stuff could be made to happen magically and automatically behind the scenes; now everything happens out in the open, explicitly.