If you look in the target information (double-click on the target to convey it), on the "Properties" tab you will see the name of the main Nib file. The words "Nib" and "Sib" are used interchangeably for this purpose; Xib is just a newer alternative for Nib.
This will be the "MainWindow" from the template. If you open MainWindow.xib, you will see that it has an object named "[project name] App Delegate", and if you show the inspector and check it on the "i" tab, you will see the type of class, which is named at the top . If you check the connections tab (right arrow), you will see that the owner of the file (which is itself UIApplication) has an attached "delegate" property.
You will also see that it has an output called 'viewController'. This is tied to another object in xib called "[project name] View Controller". Check the type and you will see its type of view controller, which Xcode has added to your project. Looking at its attributes (the first tab in the inspector with slider graphics), you will also see that a separate nib file is listed as containing its basic information.
For the sake of argument, suppose I named my project "NibTest" and made no changes.
At run time, the device loads Info.plist. There he sees that the delegate is of type NibTestAppDelegate. Thus, it will instantiate the NibTestAppDelegate class and set the UIApplication delegation property for it.
You will then see from MainWindow.nib that NibTestAppDelegate has a member named viewController of type NibTestViewController. Therefore, he will instantiate this object and set the viewController property in the NibTestAppDelegate instance that he just created.
In doing so, he will open another xib and continue with the same steps.
Objective-C has a fully reflective runtime, so you can create objects by the name of your class at runtime. This is one of the differences between Objective-C and C ++, for example.
Xcode does not generate hidden code or rely on any hidden naming conventions. All this is revealed during the operation of the OS.
EDIT: for example, instead of your example:
MyViewController *aViewController = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]];
You really can do:
MyViewController *aViewController = [[NSClassFromString(@"MyViewController") alloc] initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]];
They will work the same if MyViewController exists in the program or in a wider runtime environment.
You can alternatively pass any other string object that you like to NSClassFromString . Even ask the user if you want (although that would be a very bad idea for security reasons).