I have a UIViewController that materializes its view in loadView (i.e. no nib). Per the documentation (and via confirmation in code), loadView and consequently, viewDidLoad will not get called until UIViewController’s view is accessed the first time.
I have another class that instantiates the UIViewController and calls a number of methods on it before the view itself is referenced. Many of these methods modify the view / subviews in the UIViewController. Unfortunately, the view / subviews are not instantiated at this point. (I can easily just add a reference to the view before the other method calls, but this requires effort and understanding of an invisible contract on the user of my UIViewController).
How do I handle methods on the UIViewController which modify the view / subviews? In each of my UIViewController methods, I can check if the view is loaded, but you aren’t supposed to call loadView directly. I could put a “self.view;” in the method to presumably assure the view is loaded, but this seems pretty hackish (and of course causes a clang warning).
Additionally, this isn’t just a one time thing, since obviously the view could be unloaded during memory events, allowing this state to happen quite often.
I feel like I’m missing something fairly simple, but I haven’t been able to find it. What is the appropriate way to handle this state / initialization issue?
Basically the answer to this kind of thing is to not expose components of your views through your view controller as other objects probably shouldn’t be accessing them. So, if your view controller manages a view that renders a person’s name, for example, instead of doing something like this:
You would separate the data/model bits from the view bits and expose a ‘name’ property on your view controller. Then you can have this simple example code which always works properly (it requires a bit more code, but it saves you from headaches like this and, to be perfectly honest, is what MVC is about):
And the implementation of such a controller:
Quick Note: This was just typed up in this little box and I’m really tired, so it’s not checked for total syntax correctness, etc. It’s meant as a quick example not something to cut and paste.
Also, if you had a number of properties that needed to be updated each time, you might create a single utility method like -udpateLabels or something that updates them all. Then you call that from each setter and from viewDidLoad or loadView. That way you’ll have everything in one place (at the expense of some performance). If, after profiling, you spend too much time in that method, you can break it out as appropriate.