2009-10-22 17 views
12

Tengo un método estático que crea una instancia de la clase y la coloca en la variable estática. Me pregunto cuál es la forma correcta de administrar la memoria en esta situación.Objective-C/iPhone Administración de memoria Variables estáticas

No puede ponerlo en el método dealloc, porque aunque puede acceder a la variable estática, cualquier método de instancia creado que se libere también lanzará sharedInstance.

Supongo que puede haber una opción de crear un método de destrucción estática que liberará manualmente la memoria y puede ser invocada por el usuario desde appWillTerminate, pero eso parece un poco extraño.

Entonces, de nuevo, la pregunta: ¿Cuál es la forma correcta de liberar una variable estática?


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

Respuesta

8

Puede o no suelte ellos, lo cual está bien ya que la aplicación se está cerrando todos modos. Cocoa en el iPhone ya lo hace, no elimina por completo todo, simplemente deja que la aplicación se deslumbre.

O puede eliminarlo de appWillTerminate o de alguna otra función de apagado.

+3

Tenga en cuenta que si usted tiene un singleton una cosa que podría ser una buena idea hacer es tener algún tipo de método de limpieza, que puede ser llamado por el delegado de aplicaciones cuando recibe una advertencia de memoria baja. Incluso podría volcar todo el objeto estático en ese momento y dejar que se vuelva a crear si la creación no es demasiado costosa. –

7

Querrá echar un vistazo a "Creating a Singleton" en el centro de desarrollo de iPhone para ver cómo implementar correctamente ese patrón. No liberará su singleton, solo lo dejará morir cuando la aplicación salga.

Además, si usted está multiproceso usted probablemente querrá para envolver que alloc en un @synchronize (auto) {}

Aquí es el texto completo:

Algunas clases de Fundación y el kit de aplicación crea objetos singleton . En una implementación "estricta", , un singleton es la única instancia permitida de una clase en el proceso actual . Pero también se puede tener una aplicación más Singleton flexibles en la que un método de fábrica siempre devuelve la misma instancia, pero se puede asignar e inicializar la clase adicional instances.The NSFileManager encaja este último modelo, mientras que la UIApplication se ajusta a la ex. Cuando solicite una instancia de UIApplication, le pasa una referencia a la única instancia, asignándola e inicializándola si aún no existe.

Un objeto único actúa como una especie de centro de control, dirección o coordinación de los servicios de la clase . Su clase debe generar una instancia simple de en lugar de instancias múltiples cuando hay conceptualmente una sola instancia (como con, por ejemplo, NSWorkspace). Usted usa instancias únicas en lugar de métodos o funciones de fábrica cuando es posible que haya instancias múltiples un día.

Para crear un producto único como la única instancia permisible de una clase en el proceso actual , es necesario tener una implementación similar al listado 2-15. Este código hace lo siguiente:

Declare una instancia estática de su objeto singleton e iníciela en nil. En su método de fábrica de clase para la clase (llamada algo así como "sharedInstance" o "sharedManager"), genera una instancia de la clase pero solo si la instancia estática es nula. Invalidar allocWithZone: método para asegurarse de que no es otra instancia asignada si alguien intenta asignar e inicializar una instancia de la clase directamente en lugar de utilizar el método de fábrica clase. En su lugar, solo devuelve el objeto compartido. Implemente los métodos de protocolo base copyWithZone :, libere, conserve, retainCount, y suelte automáticamente para hacer las cosas apropiadas para asegurar el estado singleton . (Los últimos cuatro de estos métodos se aplican a código de la memoria gestionados, no código de recolección de basura.) El listado 2-15 La aplicación estricta de un MyGizmoClass estática Singleton

*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; } 

Si quiere una instancia singleton (creada y controlada por el método de fábrica de clase ) pero también tiene la capacidad de crear otras instancias según sea necesario a través de la asignación e inicialización, no invalidar allocWith Zona: y otros métodos siguiéndolo como se muestra en Listado 2-15.


ACTUALIZACIÓN: Ahora hay una manera mucho más fácil para crear un producto único

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

    return _sharedInstance; 
} 

El uso de este nuevo estilo que no es necesario preocuparse por el @syncronize o anulando la gestión de memoria métodos.

1

clase variable o estática permanece en la memoria de por vida Untill de su aplicación

Así que si no se utiliza a continuación, hacer

Your_variable = nil; 

mientras que declara el uso variable estática _datatype = nil; que ayudan al inicializar .. y la gestión de memoria

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

static MyClass *myClass = nil; 

@implementation MyClass 

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

@end