Question

In my code, I use a singleton object as a central point in my app to load and cache images the app frequently needs, so I don't have to do resource-intensive memory allocation each time I load an image.

But there are times during the execution of my app where memory usage gets intense and I would like to release the cached image data. Currently, I'm just releasing the UIImage instances from my singleton when I get a memory warning.

I would prefer, however, to be able to release the entire singleton object. Is that possible? If so, how?

Was it helpful?

Solution

Of course it is. Although it's rather likely that the memory usage of this object is negligible compared to the images.

By the nature of a singleton, you need to have an accessor for it, where you will create it if it does not currently exist:

+ (MySingletonClass*) mySingleton
{
    if ( mySingleton == nil )
    {
        mySingleton = [[MySingletonClass alloc] init];
    }

    return mySingleton;
}

You just need to add another that you call when you want to destroy it:

+ (void) destroyMySingleton
{
    [mySingleton release];
    mySingleton = nil;
}

If you keep references to it around elsewhere you'll have trouble; don't do that. If you access from multiple threads you'll need to synchronize. Otherwise, it's pretty straightforward -- the getter will recreate when you next need it.

OTHER TIPS

Here's an example of a singleton accessor for the OpenAL code I'm using.

  // Eric Wing. Singleton accessor.  This is how you should ALWAYS get
  // a reference to the sound controller.  Never init your own.
  + (OpenALSoundController*) sharedController
 {
  static OpenALSoundController* shared_sound_controller;
  @synchronized(self)
  {
   if (nil == shared_sound_controller)
    {
     shared_sound_controller = [[OpenALSoundController alloc] init];
    }
  }      
  return shared_sound_controller;
 }

OpenAL takes a while to load up so keeping one instance around is exactly what I need. With more than one thread in play (not my situation currently but I want my code to be ported to situations where this is the case) I put a lock on self. @synchronized(self) does exactly that.

Now I allocated the memory so I'm responsible for releasing it. I could call [shared_sound_controller autorelease] in the +sharedController accessor method but this may release the controller early, particularly when I have more than one thread and I call the accessor for the first time in a thread that's not the main thread.

Any object you create you can just release at any time. (Presuming you create it and set it's properties.)

self.myObject = [[myObjectClass alloc] init];
    // do something with the object
   [self.myObject release];       // anytime that you are not using the object

self.myObject = nil; // will also work if you've set the @property (retain, nonatomic)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top