简体   繁体   中英

iOs: Why are IBOutlets not wired up after [[alloc] init], but are after viewDidUnload: has been called

I have a simple UINavigationViewController which when a certain item is selected creates a modal view that has an UIImageView (PostcardViewController below) inside it. However, if I call

PostcardViewController *postcardViewController = [[PostcardViewController alloc] init];
postcardViewController.imageView.image = image; 
[self.navigationController presentModalViewController:postcardViewController animated:YES];

postcardViewController.imageView is nill, and the image never gets shown. If I switch the latter two lines, and make it:

PostcardViewController *postcardViewController = [[PostcardViewController alloc] init];
[self.navigationController presentModalViewController:postcardViewController animated:YES];
postcardViewController.imageView.image = image; 

postcardViewController.imageView is set, and it shows up fine. Everything is wired up in Interface Builder and PostcardViewController doesn't have any specific code in it. By debugging, I came to find out, that it was after [ viewDidLoad ] was called that imageView was wired up, and [ viewDidLoad ] got called when I called [ presentModalViewController ].

Why is this, and also, am I doing something wrong here? I figured I should have the entire view set up before I actually showed it, but as of right now, I have to display it before I can completely set it up.

You've only created the view controller using alloc+init, not the view itself. The view is lazily loaded, ie the first time it is used. To force the view to be created before it is actually shown, do this:

PostcardViewController *postcardViewController = [[PostcardViewController alloc] init];
postcardViewController.view; // Forces the view to be loaded
postcardViewController.imageView.image = image; // Will no longer be nil
[self.navigationController presentModalViewController:postcardViewController animated:YES];

The outlets are nil because initializing a controller doesn't load the nib/xib. Only after the view property is accessed (like when presented) is the nib loaded and wired to controller.

Let the PostcardViewController have the responsibility of setting the imageView's image in viewDidLoad. Create an image property to pass the UIImage.

PostcardViewController *pvc= [[PostcardViewController alloc] init];
pvc.image = image; 
[self.navigationController presentModalViewController:pvc animated:YES];
[pvc release];

In PostcardViewController.h

  ...
  UIImage *image
}
@property (nonatomic, retain) UIImage *image;

In PostcardViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];
    imageView.image = image;
}

It's because UIViewControllers load their views lazily. So the view isn't loaded until you actually attempt to present it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM