Управление памятью объекта Singleton - PullRequest
0 голосов
/ 05 августа 2010

В моем коде я использую одноэлементный объект в качестве центральной точки в моем приложении для загрузки и кэширования изображений, которые часто нужны приложению, поэтому мне не приходится делать ресурсоемкое выделение памяти при каждой загрузке изображения. 1001 *

Но бывают случаи, когда во время выполнения моего приложения интенсивно используется память, и я хотел бы выпустить данные кэшированного изображения. В настоящее время я просто освобождаю экземпляры UIImage из моего синглтона, когда получаю предупреждение о памяти.

Я бы предпочел, однако, иметь возможность высвобождать весь одноэлементный объект. Это возможно? Если да, то как?

Ответы [ 3 ]

2 голосов
/ 05 августа 2010

Конечно, это так.Хотя вполне вероятно, что использование этого объекта в памяти незначительно по сравнению с изображениями.

По природе одиночного, вам нужен механизм доступа к нему, который вы создадите, если он в настоящее время отсутствует.Существовать:

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

    return mySingleton;
}

Вам просто нужно добавить еще один, которому вы звоните, когда хотите уничтожить его:

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

Если вы будете хранить ссылки на него где-то еще, у вас будут проблемы;не делай этогоЕсли вы получаете доступ из нескольких потоков, вам нужно синхронизировать.Иначе, это довольно просто - получатель воссоздает, когда вам это понадобится в следующий раз.

1 голос
/ 04 марта 2011

Вот пример одноэлементного метода доступа для кода OpenAL, который я использую.

  // 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 требуется некоторое время, поэтому мне нужен только один экземпляр. Поскольку в игре находится более одного потока (в настоящее время это не моя ситуация, но я хочу, чтобы мой код переносился в ситуации, в которых это происходит), я установил блокировку на self. @synchronized(self) делает именно это.

Теперь я выделил память, поэтому я отвечаю за ее освобождение. Я мог бы вызвать [shared_sound_controller autorelease] в методе доступа +sharedController, но это может привести к преждевременному освобождению контроллера, особенно когда у меня более одного потока, и я впервые вызываю метод доступа в потоке, который не является основным потоком.

0 голосов
/ 05 августа 2010

Любой созданный вами объект можно просто отпустить в любое время.(Предполагается, что вы создадите его и установите его свойства.)

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...