2009-10-22 3 views
12

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

Вы не можете поместить его в метод 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 

ответ

8

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

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

+3

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

7

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

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

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

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

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

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

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


UPDATE: Существует в настоящее время гораздо более простой способ создать синглтон

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

    return _sharedInstance; 
} 

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

1

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

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

Your_variable = nil; 

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

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

static MyClass *myClass = nil; 

@implementation MyClass 

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

@end 
Смежные вопросы