Objective-C / iPhone Управление памятью Статические переменные - PullRequest
12 голосов
/ 22 октября 2009

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

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

Я полагаю, что может быть вариант создания статического метода уничтожения, который вручную освободит память и может быть вызван пользователем из 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

Ответы [ 3 ]

8 голосов
/ 22 октября 2009

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

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

7 голосов
/ 23 октября 2009

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

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

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

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

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

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

Объявление статического экземпляра вашего объект Singleton и инициализировать его ноль. В вашем классе фабричный метод для класс (назвал что-то вроде «SharedInstance» или «sharedManager»), создать экземпляр класса, но только если статический экземпляр равен нулю. Переопределить allocWithZone: метод для убедитесь, что другой экземпляр не выделяется, если кто-то пытается выделить и инициализировать экземпляр вашего класс непосредственно вместо использования метод фабрики классов. Вместо этого просто вернуть общий объект. Воплощать в жизнь методы базового протокола copyWithZone :, освободить, сохранить, retainCount и авто-релиз, чтобы сделать соответствующие вещи, чтобы обеспечить синглтон статус. (Последние четыре из них методы применяются к коду, управляемому памятью, не собирать мусор.) Перечисление 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; }

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


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

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

  return _sharedInstance;
}

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

1 голос
/ 11 июля 2011

статическая переменная или класс остаются в памяти до времени жизни вашего приложения

Так что, если оно не используется, тогда сделайте

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
...