It's not necessarily incorrect to have a 2:1 ratio of .xib to controller class in the case of a Universal App. Here's the pattern I follow:
You have your MainViewController class. You have 2 .xib files: MainView-iPhone.xib and MainView-iPad.xib. Both of these file have their "File's Owner" outlet set to MainViewController. Now, to ensure the view controller actually loads the correct interface and connects all the right outlets depending upon the device on which the app is running, I'll do something like the following:
MainViewController* controller = nil;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
controller = [[MainViewController alloc]initWithNibName:@"MainView-iPad" bundle:[NSBundle mainBundle]];
} else {
controller = [[MainViewController alloc] initWithNibName:@"MainView-iPhone" bundle:[NSBundle mainBundle]];
}
/* Present the controller */
Now, I should also say that this is only a good idea if there aren't too many distinct code paths that need to be followed when run on different devices. If the controller's behavior is more specialized when running on an iPad vs. and iPhone, it's a better idea to abstract the common behavior in MainViewController and then write two sublasses: MainViewController_iPhone and MainViewController_iPad. Each subclass then loads the appropriate .xib file and handles all of the specifics internally. In this case, the above code would look more like:
MainViewController* controller = nil;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
controller = [[MainViewController_iPad alloc] init];
} else {
controller = [[MainViewController_iPhone alloc] init];
}
/* Present the controller */