views:

258

answers:

4

I've got a few apps under my belt now, but I'm still relatively new to this. I'm looking for best practices advice or even a feature of the Cocoa Touch framework that I wasn't aware of, if anybody knows it.

In the 1st app, I created Domain Objects in my Application Delegate, then would pass them off to my ViewControllers as needed. For example, in the App Delegate I'd try to load the user's account from memory, and if it was there I'd create an Account object using initWithCoder. Then, whenever I instantiated a ViewController that needed the Account object, I would pass it to that ViewController which had its own account property.

However I felt like I had too much code in my app, so I decided instead to have my ApplicationDelegate manage my Domain Objects. Whenever a ViewController needed one it would query the ApplicationDelegate like so:

MyAppDelegate* myAppDelegate = [UIApplication sharedApplication].delegate;
ADomainObject* anObject = myAppDelegate.anObject;

Is this insane? Is it a good idea? I totally made it up on my own so I'm wondering if anything better is out there. Since I'm new to iPhone dev, I'm trying to learn the best way to do things...

+2  A: 

No, it's not a bad design. You might want to look into using the Singleton pattern as an alternative or, more likely, a complement to the App Delegate idea. You would be able to write things like

[ADomainObject sharedDomainObject]

to get your object. Class methods are also a good way to get domain objects in a single-document application -- as all iPhone applications are single document. If you had, say, a hierarchy of Folder objects, you might have a class method like + (NSArray *)rootFolders or + (NSArray *)allEmptyFolders to get specific groups of objects.

Alex
Interesting, although not all of my Domain Objects are appropriate for singletons. For example, a collection of Domain Objects. Although in that case, I suppose I could create a Category for that Collection class?Do you mind clarifying what you mean by "single document" application?
bpapa
You could implement accessors for your collections as class methods on that domain object class. Whether they live in a category is up to you. On the desktop you can have multiple windows for multiple files. This doesn't apply to iPhone, but there are ideas in NSDocument that might interest you.
Alex
Appkit-based Cocoa applications are often either "document-based" or "single-window" (aka "single document") applications, which means they can either have multiple documents open (like a text editor) or only one at a time. I think what Alex is saying is that iPhone apps are more like the latter.
erikprice
Yep, that's exactly what I meant. Thanks for saying it better than I did.
Alex
+2  A: 

What you described works; I've used the same strategy when dealing with Core Data on the desktop, where my application has a single managed object context owned by the application controller. Besides singletons as Alex mentioned, one other common strategy is to implement a "data controller" that handles the logic of loading and managing your domain objects. In this case your application controller would still be responsible for initializing and managing the relationships between the data controller and view controllers, but it wouldn't be cluttered with model object specific code.

Marc Charbonneau
+1  A: 

In non-Cocoa application development that I've done, I've found it helpful to use the DI approach, where objects have their dependency objects (in this case, your domain objects) handed to them from outside, rather than reaching out and asking for them explicitly. "Asking for them explicitly" would mean something along the lines of what you are currently doing - accessing them via properties on your application delegate. Is it possible/easy/foolish to create associations between ViewControllers and the domain objects in some fashion, so that the ViewControllers don't have to explicitly ask for them? For example, is there a way to establish these relationships in the nib? I'm asking, not advising, since I'm no expert on Cocoa. (Sorry to piggyback my question on this thread but it's pretty related to the original question.)

erikprice
As I'm primarily a Java guy and a big fan of the Spring Framework I am very familiar with DI... I kinda diverged from it for my approach here. You are correct though, my ViewControllers now do have a dependency on the App Delegate.
bpapa
+1  A: 

I wouldn't have the app delegate involved at all. The View controller instantiates and owns the model object if there's only one controller using that object. Otherwise I use a Class-level method to retreive a static instance of the model, with a +[DatabaseModel sharedDatabaseModel] method.