开发者

What's the Best Way to Send Parameters to a UIViewController?

I ask this question because it appears that viewDidLoad gets called before the main block of the initializer does and the class variables I'm initializing in the initializer are turning up nil in viewDidLoad. For your reference, I'm doing this entire viewcontroller programmatically and I've created a custom initializer so I can take in various parameters to be used in my viewcontroller. My custom initializer calls UIViewControllers designated initializer of course.

Basically, I'm curious about what is the proper design pattern for sending in parameters to a UIViewController? I've read other threads about this and haven't really gotten a开发者_C百科 definitive answer. Should I just skip the initializer and set the properties manually (from outside the class)? That seems kind of bleh, I'd really like to send in some parameters and am curious how others go about doing this?


The reason viewDidLoad is called before initialization completes, is probably because you call the view method in the initializer. For example:

- (id)init
{
    if ((self = [super init])) {
        _thing = 123;
        _other = self.view.frame.size.width / 2;
    }

    return self;
}

viewDidLoad is called when the view loads. And the view loads as soon as you call the view method (or access the view property, if you prefer). So you should avoid referencing the view in init.

To answer your question, I prefer to create an init method for my view controllers.

- (id)initWithThing:(MyThing *)thing thang:(MyThang *)thang
{
    if ((self = [super init])) {
        _thing = [thing retain];
        _thang = [thang retain];
        // ...
    }

    return self;
}

You can also use properties to set extra variables after initing. Personally I prefer to do this with optional properties only, though, and put required properties in the init method. That way I can't init the view controller with an invalid state.


I encapsulate the state of my controllers in an additional state object. So the controller usually has ivars for the GUI elements and a reference to this state object.

State objects are handled by a StateManager object on my delegate. So instead having a controller referencing another controller and set variables directly, all changes go through this manager. A little more work but way less messy.

Any class is able to retrieve the state for any other controller and change it. This is the purpose of some controllers (eg: choosing a video from youtube happens on a dedicated controller). But usually is just one class getting a state to push the next controller with initWithState:. The pushed controller then applies the state to its GUI in viewDidLoad or changes this state object passed from the previous class.

The StateManager keeps a dictionary of all the state objects. I keep the state object graph light, eg: I store a reference to a image, but not the image itself. The real beef of the application is in Core Data, I only use all this to handle the GUI state. The StateManager listens for the application resign event and saves the state dictionary to disk using NSCoding. The state object ivars are always nil or some meaningful value, no dangling pointers.

I'm working on my 2nd iPhone app and this seems to be working, but I wonder too how other people does it. Any input is welcome.


Basically you should have properties defined for your input data but add a custom init-function.
If you create a custom init-Method you should be fine - remember that initWithNibName:bundle: is the main initializer of UIViewController so this is what you want to call from your custom init-Method. viewDidLoad will always be called after your init-Method at the first usage of customVC.view (either from your code or via Framework):

- (id)initWithDataObject:(MyDataObject*)obj
{
    self = [super initWithNibName:nil bundle:nil];
    if (self) {
        self.dataObj = obj;
    }
    return self;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜