2009-10-22 6 views
12

Mam statyczną metodę, która tworzy instancję klasy i umieszcza ją w zmiennej statycznej. Zastanawiam się, jaki jest właściwy sposób zarządzania pamięcią w tej sytuacji.Zarządzanie zmiennymi systemowymi Objective-C/iPhone

Nie można umieścić go w metodzie dealloc, ponieważ chociaż może uzyskać dostęp do zmiennej statycznej, to każda metoda instancji, która jest tworzona, która zostanie wydana, zwolni również parametr sharedInstance.

Domyślam się, że istnieje możliwość stworzenia metody statycznego niszczenia, która będzie ręcznie zwalniać pamięć i może zostać wywołana przez użytkownika z appWillTerminate, ale wydaje się to nieco dziwne.

Jeszcze raz pytanie: Jaki jest właściwy sposób zwalniania zmiennej statycznej?


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

Odpowiedz

8

Nie można też je zwolnić, co jest w porządku, ponieważ aplikacja jest zamykany tak. Kakao na iPhonie już to robi, nie usuwa całkowicie wszystkiego, po prostu pozwala aplikacji odejść.

Lub możesz go usunąć z appWillTerminate lub innej funkcji wyłączania.

+3

Pamiętaj, że jeśli masz singleton jedno może to być dobry pomysł, aby zrobić, to mieć jakieś metody oczyszczania, które mogą być wywołane przez delegata aplikacji kiedy otrzyma ostrzeżenie o małej ilości pamięci. Można nawet zrzucić cały statyczny obiekt w tym czasie i pozwolić mu go odtworzyć, jeśli tworzenie nie jest zbyt kosztowne. –

7

Będziesz chciał rzucić okiem na "Creating a Singleton" w centrum programowym iPhone'a, aby zobaczyć, jak prawidłowo zaimplementować ten wzorzec. Nie uwolnisz swojego singletona, tylko pozwolisz mu umrzeć, gdy aplikacja wyjdzie.

Ponadto, jeśli jesteś wielowątkowe prawdopodobnie będziesz chciał zawinąć że Alloc w @synchronize (samo-) {}

Oto pełny tekst:

Niektóre klasy i Fundacji Zestaw aplikacji tworzy obiekty singleton . W "ścisłej" implementacji singleton jest jedyną dozwoloną instancją klasy w bieżącym procesie . Ale można też mieć bardziej elastyczną realizację singleton w którym metoda fabryki zawsze zwraca tego samego wystąpienia, ale można przeznaczyć i zainicjować dodatkową klasę instances.The NSFileManager pasuje ten ostatni wzór, natomiast UIApplication pasuje do były. Kiedy pytasz o instancję o numerze UIApplication, przekazuje ono odniesienie do jedynego wystąpienia, przydzielanie i inicjowanie go, jeśli nie istnieje jeszcze .

Obiekt singletonowy działa jako rodzaj centrum sterowania, kierując lub koordynujący usługi klasy . Twoja klasa powinna generować instancję singleton , a nie wiele wystąpień, gdy istnieje koncepcyjnie tylko jedna instancja (jako z, na przykład, NSWorkspace). Ty używaj pojedynczych instancji zamiast fabrycznych metod lub funkcji, gdy jest możliwe, że może być wiele wystąpień jednego dnia.

Aby utworzyć singleton jako jedynego dopuszczalnego instancji klasy w bieżącym procesie , trzeba mieć realizacji podobny do listingu 2-15. Ten kod wykonuje następujące czynności:

Zadeklaruj statyczną instancję pojedynczego obiektu i zainicjuj ją na zero. W swojej fabrycznej metodzie klasy dla klasa (o nazwie coś w rodzaju "sharedInstance" lub "sharedManager"), generuje instancję klasy, ale tylko wtedy, gdy statyczna instancja jest zerowa. Zastąpić allocWithZone: metodę upewnić się, że kolejna instancja nie jest przydzielone jeśli ktoś próbuje przydzielić i zainicjować instancję klasy bezpośrednio zamiast przy użyciu metody fabryki klasy. Zamiast tego tylko zwraca obiekt współdzielony. Implementacja podstawowych metod protokołu copyWithZone :, release, retain, retainCount i autorelease, aby wykonać odpowiednie rzeczy, aby zapewnić status singleton . (Ostatnie cztery z tych metod stosuje się do pamięci zarządzane kodu nie do śmieci zgromadzone w kodzie). listingu 2-15 ścisłego pojedyncza statyczny 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; } 

Jeśli potrzebujesz pojedynczej instancji (utworzonej i sterowanej metodą klasy fabrycznej ), ale także mają możliwość tworzenia innych instancji w razie potrzeby poprzez przydzielanie i inicjowanie, nie zastępuj allocWith Strefa: i inne metody następujące po niej, jak pokazano na liście 2-15.


UPDATE: Istnieje obecnie wiele łatwiejszy sposób, aby utworzyć singleton

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

    return _sharedInstance; 
} 

Stosując ten nowy styl nie trzeba się martwić o @syncronize lub przesłanianie zarządzanie pamięcią metody.

1

zmienna statyczna lub klasa pozostaje w pamięci aż trwania aplikacji

więc jeśli nie jest używany wtedy zrobić

Your_variable = nil; 

podczas deklarowania użycia zmiennej statycznej _datatype = nil; który pomaga podczas inicjalizacji .. i zarządzanie pamięcią

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

static MyClass *myClass = nil; 

@implementation MyClass 

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

@end