I am writing an application that needs to interfaces with different backend systems. I decided to use a Protocol in order to abstract my backend Classes. I created a nib called LoginViewController that contains an “External Object” reference of type “NSObject”, and wired it to the systemDelegate outlet in my LoginViewController.
@interface LoginViewController : UIViewController {
}
@property (nonatomic, retain) IBOutlet UITextField *usernameTextView;
@property (nonatomic, retain) IBOutlet UIImageView *captchaImageView;
@property (nonatomic, retain) IBOutlet UITextField *captchaTextView;
@property (nonatomic, retain) IBOutlet NSObject <BackEndSystemDelegate> *systemDelegate;
- (IBAction) submitCaptcha:(id) sender;
- (IBAction)dismissKeyboard: (id)sender;
- (IBAction) animateViewUp: (id) sender;
- (IBAction) animateViewDown: (id) sender;
- (void) animateViewOnYAxis: (int) offset;
- (void) loadCaptchaImage;
@end
I instanciate the LoginViewController in my application delegate, then try to load the nib with the external object reference. My code calls the loadNibNamed and crashes without a stack trace. I do not reach the NSLog statements after the invocation:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSObject <BackEndSystemDelegate> *systemDelegate = [[ACMEBackEndSystemDelegate alloc] init];
// Init LoginView, and load nib with systemDelegate
self.viewController = [[LoginViewController alloc] init];
NSDictionary *proxies = [NSDictionary dictionaryWithObject:systemDelegate forKey:@"systemDelegate"];
NSDictionary *options = [NSDictionary dictionaryWithObject:proxies forKey:UINibExternalObjects];
NSArray *toplevelobjects = [[NSBundle mainBundle] loadNibNamed:@"LoginViewController"
owner:self.viewController
options:options];
if (toplevelobjects) {
NSLog(@"toplevelobjects is nil");
} else {
NSLog(@"toplevelobjects count %d", [toplevelobjects count]);
}
NSLog(@"Controller: %@, View: %@", viewController, viewController.view);
// Add the view controller's view to the window and display.
[window addSubview:viewController.view];
[window makeKeyAndVisible];
return YES;
}
I am at a loss trying to figure this out. Any help would be appreciated.
Thanks,
J Garcia
A few comments:
Generally you refer to a delegate object using the pattern
id<SomeProtocolName>and notNSObject<SomeProtocolName>You
allocyoursystemDelegatevariable but neverreleaseit. This is a memory leak.If the
ACMEBackEndSystemDelegateclass implements theBackEndSystemDelegateprotocol, it is sufficient to allocate it likeACMEBackEndSystemDelegate* systemDelegate = [[ACMEBackEndSystemDelegate alloc] init];Now, as for your crash, you said there’s a crash on this line:
I assume you have a .xib called
LoginViewController.xib. Open it up. That is the class type set for “File’s Owner”? Is itLoginViewController? If not, set it. Now check theviewoutlet property. Is it set to aUIViewin the .xib (perhaps a top-levelUIViewobject)? If not, set it.