Objective C & iOS Weak Singletons


Temporary shared memory management is always a bit of a difficult problem to solve. There are various well known ways of dealing with this problem but recently i’ve come across a novel solution to this problem that actual takes advantage of Objective C’s Automatic Reference Counting (although it could also work without ARC)

The singleton pattern is used in quite a lot of applications i’ve worked on, usually it retains some objects in memory and can exist for the lifetime of the application. Other times it’s only useful for a specific part of the application and can be disposed of when finished. Disposing of no longer needed singletons isn’t the easiest thing to deal with, but this pattern hopefully should solve the problem.

I’d like to introduce you to my new friend the weak singleton. Essentially the weak singleton works in exactly the same way as any other singleton, the difference is that when it’s retain count drops to zero it’s automatically destroyed.

While this is awesome for memory management it also means you need to hold a reference to the singleton to keep it alive, this is usually done in an ivar:

{
    ASingletonClass *_singletonInstance;
}

And then when you first use it:

_singletonInstance = [ASingletonClass sharedInstance];

If you have a chain of view controllers that need this singleton as part of your navigation each one of those will need to implement the same code and hold a reference to the singleton. What this means is that only one singleton will existing in memory, and providing something is holding a reference to the singleton any new views will get the same one.

At this point if you were to dismiss all the view controllers and release all the references the retain count will drop to zero, because the singleton only holds a weak reference to itself it will then be entirely released from memory. If you go back into any of the view controllers a call to the singleton class method ‘sharedInstance’ will create a new singleton which will again exist until it’s released.

This is a really useful for managing temporary memory. I’ve used it recently for holding texture information to display in an OpenGL view.

So here’s the code used to create one (i’m presuming you’re familiar with the singleton pattern in objective c at this point):

+ (id)sharedInstance
{
    static __weak ASingletonClass *instance;
    ASingletonClass *strongInstance = instance;
    @synchronized(self) {
        if (strongInstance == nil) {
            strongInstance = [[[self class] alloc] init];
            instance = strongInstance;
        }
    }
    return strongInstance;
}

It works in a very similar way to the ‘old style’ singleton creation in Objective C. The major difference is it creates a strong reference to the weak reference to avoid any race condition where ARC clears the memory part way through requesting the singleton. Hopefully you’ll find some uses for this in your code, if you do though i’d like to hear how you’ve used it.

, , ,

  1. No comments yet.
(will not be published)