The worst choice IMO is to store things in the app delegate. See What describes the Application Delegate best? How does it fit into the whole concept? for much more on that. In short, the app delegate is the Application Delegate. It is not "the Application Dumping Ground for Globalish Things."
Singletons are a long-established approach in ObjC, via the shared...
pattern. After decades of popularity, and extensive use within the core Cocoa frameworks (NSUserDefaults
, NSNotificationCenter
, NSApplication
, NSFontManager
, NSWorkspace
, UIDevice
, etc. etc. etc.), they have in recent years fallen into some disregard in favor of other techniques, particularly "dependency injection," which is just to say "assigning to a property."
After years of using singletons in ObjC, I am coming around to the DI way of thinking. The improvements in testability and the improved clarity of dependencies are quite nice. That said, sometimes DI can lead to awkward transitions, particularly when dealing with storyboards.
So, I would say:
- When practical, just construct objects and assign them to properties on the objets that need them.
- If you have a lot to pass around, consider collecting them into a single "configuration" object and pass that around (but this hurts modularity somewhat).
- If DI creates chaos (particularly if it leads to a lot of passing objects to things just so they can pass the object on to something else), or if it forces a lot of storyboard segue code that you could otherwise avoid, singletons are a well-established and well-respected pattern in Cocoa and are not wrong. They are a Cocoa Core Competency.
- If you ever find yourself calling
(MyAppDelegate *)[[UIApplication sharedApplication] delegate]
, then you're doing something wrong.