What is a good way to get a reference to “singleton” objects in Objective-C? Note, specifically, I am not referring to the singleton pattern, I am referring to objects of which there are normally only one instance. This specifically applies to application models. For example, in a cooking app, I would like a class (RecipeModel) that can give me an NSArray of all the “Recipe” objects in my system.
I wouldn’t want to load these from persistent storage every time — it would make sense to load them once and then cache them in memory (in a variable on this class, in other words). If I do this, several of my classes will probably need a way to get to this instance.
What is the most flexible way to do this? Here are all the options I can think of.
- Make RecipeModel a real Singleton, with a +(RecipeModel *) sharedRecipeModel method
- Make the allRecipes NSArray accessible via a class method. Each viewController could then create a new RecipeModel and would get the same (static/global) data. +(NSArray *) allRecipes
- Create it in appDelegate and use the sharedApplication to get a reference to it
- Make sure everything is in interface builder, and use an IBOutlet to pass a copy of the class to my viewController
On other platforms (flex) I would use a DependencyInjection or MVC framework to handle this kind of wiring. I’ve read that objective-c doesn’t “need” a DI framework because it has categories. I don’t know enough to evaluate that, but categories certainly don’t solve this problem.
I think you’re over complicating this.
There is no reason to create a singleton class when all you need is just a generic collection object that all your other objects have access to.
The best way to give universal access to some object is to park it in the application delegate. In the case you suggested you would have something like:
Then anywhere in your app you could call:
No fuss, no muss.
If you’re using Core Data you can just park the
NSManagedObjectContextobject in the app delegate and access that directly. Core Data has enormous optimizations that make it as fast as more primitive hand rolled methods. I wouldn’t bother trying to create a separate array unless you test and find that the direct Core Data is to slow. In the case you gave, it won’t be.