I'm new to writing singletons and I have to use one for a current iOS project. One of the requirements is that it can be killed. I know this goes against the design of a singleton, but is this something that should/could be done?
Of course it could be done, but if you're looking for an object that can be created, and then released when not needed... that sounds like a regular object. :)
Generally singletons control their own lifecycles. You're going to get one-sided discussion here unless you say more about the two requirements (one, that you use a singleton, and two, that it can be released at will), and why they both make sense in your case.
It might be because the singleton wraps some other resource that is inherently unique (like a file resource or network connection). If this is true, then generally the singleton is the "manager" of that resource, and you'd expose control of that resource via the singleton's interface.
Or it might be because the singleton object holds on to a ton of memory (a buffer of some sort), and you want to be sure that's flushed as necessary. If this is the case, then you can be smarter about each of its methods creating and releasing memory as necessary, or you can have the singleton listen for the low memory system notifications and behave appropriately.
Essentially, I'd be hard pressed to construct a case where it really made sense for the singleton object itself to be released. A single basic object takes only a handful of bytes in memory, and hurts no one by hanging around.
I know this goes against the design of a singleton
It also goes against the usual memory management patten in Objective-C. Normally, an object gets to retain another object to prevent it from being destroyed, and to release it to allow the object to be destroyed. Explicitly destroying an object, though, isn't something that other objects get to do.
Consider what would happen if object A gets the shared instance S1 of a singleton class S. If A retains S1, S1 will continue to exist even if some class method releases S and sets the global variable that points to the shared instance to nil. When the class later creates a new shared instance, S2, there will be two instances of S, namely S1 and S2. This violates the property that defines the singleton in the first place.
You might be able to get around this problem by overriding -retain
and maybe swizzling -release
, but that seems like a lot of complexity to solve a problem that shouldn't exist in the first place.
A possible alternative is to reset your shared object instead of trying to destroy it. You could set all it's attributes to some known (possibly invalid) state if you want, and then have a class method the re-initializes the shared object. Just be aware of the effect of all that on any objects that might be using the shared object.
Just about every singleton I've ever written (save for totally UI centric controllers) end up being refactored into not being singletons. Every. Single. One.
Thus, I've stopped writing singletons. I write classes that maintain state in instances, as any normal class should, and do so in isolation from other instances. If they are notification heavy, they always pass self
as the notifying object. They have delegates. They maintain internal state. They avoid globals outside of truly global state.
And, often, there may be exactly one instance of said class in my app(s). That one instance acts like a singleton and, in fact, I might even create a convenient way of getting a hold of it, likely through the App's delegate or through a class method (that might even be named sharedInstance
sometimes).
Said class includes tear-down code that is typically divided in two pieces; code to persist current state for restoration later and code that releases instance associated resources.
Convenient like a singleton. Ready to be multiply instantiated when needed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With