Подтвердить что ты не робот

Objective-C/Управление памятью в iPhone. Статические переменные

У меня есть статический метод, который создает экземпляр класса и помещает его в статическую переменную. Мне интересно, каков правильный способ управления памятью в этой ситуации.

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

Я предполагаю, что может существовать возможность создания метода static destroy, который будет вручную освобождать память и может быть вызван пользователем из appWillTerminate, но это кажется немного странным.

Итак, опять же, вопрос: Каков правильный способ выпуска статической переменной?


// MyClass.m
#import "MyClass.h"

static MyClass *myClass; // How to properly do memory management

@implementation MyClass

+ (MyClass *)sharedMyClass {
    if (myClass == nil) myClass = [[MyClass alloc] init];
    return myClass;
}
@end
4b9b3361

Ответ 1

Вы можете либо не выпускать их, но это нормально, так как приложение все равно закрывается. Cocoa на iPhone уже делает это, он не полностью удаляет все, это просто позволяет приложению сдуться.

Или вы можете удалить его из appWillTerminate или какой-либо другой функции выключения.

Ответ 2

Вам нужно взглянуть на "Создание Singleton" в центре dev для iPhone, чтобы увидеть, как правильно реализовать этот шаблон, Вы не будете выпускать свой синглтон, просто позволяя ему умереть, когда приложение выйдет.

Кроме того, если вы многопоточно, вы, вероятно, захотите обернуть это выделение в @synchronize (self) {}

Вот полный текст:

Некоторые классы Фонда и Application Kit создает синглтон объекты. В "строгой" реализации, одноэлемент является единственным допустимым экземпляр класса в текущем обработать. Но у вас также может быть больше гибкая реализация singleton в который всегда возвращает метод factoryтот же пример, но вы можете выделять и инициализировать дополнительные экземпляров. Класс NSFileManager подходит этот последний образец, тогда как UIApplication соответствует первому. когда вы запрашиваете экземпляр UIApplication, он передает вам ссылка на единственный экземпляр, выделяя и инициализируя его, если он еще не существует.

Одноэлементный объект действует как своего рода центра управления, управления или координации услуг класс. Ваш класс должен генерировать singleton, а не несколько случаев, когда есть концептуально только один экземпляр (как с, например, NSWorkspace). Вы используйте экземпляры singleton, а не factory методы или функции, когда он можно предположить, что может быть несколько экземпляров в один прекрасный день.

Чтобы создать синглтон в качестве единственного допустимый экземпляр класса в текущий процесс, вам необходимо иметь реализация аналогична листингу 2-15. Этот код выполняет следующие действия:

Объявить статический экземпляр вашего singleton и инициализировать его ноль. В вашем классе factory метод для класс (названный как-то вроде "sharedInstance" или "sharedManager" ), сгенерировать экземпляр класса, но только если статический экземпляр равен нулю. Переопределить метод allocWithZone: убедитесь, что другой экземпляр не выделяется, если кто-то пытается выделить и инициализировать экземпляр вашего класса, вместо использования класса factory. Вместо этого просто вернуть общий объект. Воплощать в жизнь методы базового протокола copyWithZone:, release, сохранить, saveCount и autorelease, чтобы выполнить подходящие вещи, чтобы обеспечить синглтон положение дел. (Последние четыре из этих методы применяются к управляемому памяти коду, а не сборку мусора.) Листинг 2-15 Строгая реализация одноэлементный статический MyGizmoClass

 *sharedGizmoManager = nil;  
 + (MyGizmoClass*)sharedManager {
     if (sharedGizmoManager == nil) {
         sharedGizmoManager = [[super allocWithZone:NULL] init];
     }
     return sharedGizmoManager; }  
 + (id)allocWithZone:(NSZone *)zone {
     return [[self sharedManager] retain]; }

 - (id)copyWithZone:(NSZone *)zone {
     return self; }

 - (id)retain {
     return self; }

 - (NSUInteger)retainCount {
     return NSUIntegerMax;  //denotes an object that cannot be released }

 - (void)release {
     //do nothing }

 - (id)autorelease {
     return self; }

Если вам нужен экземпляр singleton (созданный и управляемый классом factoryметод), но также имеют возможность создавать другие экземпляры по мере необходимости через распределение и инициализацию, не переопределяйте allocWithZone: и другие методы, следуя за ним, как показано в Листинг 2-15.


ОБНОВЛЕНИЕ: Теперь существует гораздо более простой способ создания singleton

+ (MyClass*)sharedInstance
{
  static MyClass* _sharedInstance = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    _sharedInstance = [[MyClass alloc] init];
  });

  return _sharedInstance;
}

Используя этот новый стиль, вам не нужно беспокоиться о @syncronize или переопределять методы управления памятью.

Ответ 3

статическая переменная или класс остается в памяти до срока службы вашего приложения

Итак, если это UnUsed, сделайте

Your_variable = nil;

при объявлении использования static _datatype variable = nil; которые помогают при инициализации.. и управлении памятью

///**************************
// MyClass.m
#import "MyClass.h"

static MyClass *myClass = nil;

@implementation MyClass

+ (MyClass *)sharedMyClass {
    if (myClass == nil)
            myClass = [[MyClass alloc] init];
    return myClass;
}

@end