I have been wondering for a while, after asking different people and without any of them providing what I would call an "at least a bit concrete answer":
Question:
Where, in an iPhone application should an application keep the references to it's Model Classes (using the MVC approach) ?
In iPhone (and Cocoa) applications we have what we call the "App Delegate", which basically start's up our application and inits our controllers, also handles UITouch events.
So is the App Delegate a controller ? a model class ? none of the two ? I think not knowing that also makes confusing to know where to put the Model References.
Example:
You have the Application Delegate, that delegate contains a reference to your Application's View Controller. If my Application would use Model Class A ( which is a webserver daemon class ), and a Class B which stores data queried by that webserver.
Where would you guys store the references to A and B ? (App Delegate ? View Controller ? Both ? )
There are many options here, but as an example, I would really like to know how would you guys use mvc to put together this application which only uses one View.
It is tempting to put everything in the AppDelegate, but if you start doing this, then your AppDelegate will be full of reference hacks. If you are doing a strict MVC, then you should have 3 things:
- A Model
- A View Controller (Only for view logic)
- A Controller (For coordinating between the view and the model)
So for example, I have a model Foo and a Foo controller. I would have:
- Foo.m (Model)
- FooViewController.m (Displays a Foo)
- FooController.m (Controls the logic)
And finally, to answer your question, I would store my references to Foo's in the foo Controller. I like to use singletons for my controllers, but thats just me. If you do use a singleton, you can just do something like this: [[FooController sharedInstance] listOfFoos]
to get your Foo's
In my applications I usually rename the AppDelegate class to AppController, if that helps explain things better conceptually. Your app controller is responsible for creating and/or configuring the model controller (which manages your collection of model objects) and window or view controllers, setting up references between them if needed, and calling methods on these controllers in response to NSApplication delegate methods or high level action methods from the main menu. Depending on how complex your application is you might also have additional model or view controllers which are created outside your app controller.
Of course if you have a simple application there's no real reason not to have your app controller play the role of the model controller if you want. What you want to avoid is file with hundreds of lines of code, all doing conceptually unrelated tasks.
Traditionally the controller creates the Model and then initialises the View with that model. The controller then listens to changes in the model and view and coordinates the flow of the program through this. That would be my generic answer, maybe things in practice would be different for iPhone development.
Where, in an iPhone application should an application keep the references to it's Model Classes ( using the MVC approach) ?
The controller layer keeps references to the model layer.
So is the App Delegate a controller ? a model class ? none of the two ?
The App Delegate is a controller.
Where would you guys store the references to A and B ?
A and B are model classes that would usually be created and owned by the controller layer.
I would really like to know how would you guys use mvc to put together this application which only uses one View.
The purpose of the controller layer is to allow the model and view layers to be self-contained. The model shouldn't know anything about the controller or view layers. The view shouldn't know anything about the controller or model layers. The controller's job is to be a double-ended adapter to the model on one side and the view on the other.
I would set up your example app like this:
- UIApplication delegates to AppDelegate.
- If operation of your server class (A) is simple:
- AppDelegate creates and owns instance(s) of server class A.
- If operation of your server class (A) is complicated:
- Create a dedicated controller class (C) to control the server.
- AppDelegate creates and owns instance(s) of class C. One instance of (C) for each instance of (A).
- Each instance of class C creates and owns one instance of class A.
- AppDelegate creates and owns an instance of your ViewController class, which loads and owns your view.
It's not clear in the question what the purpose of class B is.
- If it's a chunk of data that's for the use of A only (like config data or static website data), I would have it be created and owned by the server (A).
- If it's data that is created during server operation and needs to be displayed in the view, then you will probably want something like:
- A mutable array owned by A, to hold instances of B.
- Another controller class (D) to reference that array and act as a datasource/delegate to your view.
I find that in most instances, AppDelegate provides a good place to place some base functionality (such as a a background image you want applied in every controller), but that you'll want to have additional controllers and model code elsewhere. A navController or rootController would often be placed as a property on your AppDelegate.
So, I would say that is somewhere between "neither" and "controller", but leaning more towards "neither". Definitely not "model"!