Buscar..


Conteo automático de referencias

Con el recuento automático de referencias (ARC), las inserciones del compilador retain , release y autorelease donde se necesitan, por lo que no tiene que escribirlas usted mismo. También escribe métodos dealloc para usted.

El programa de muestra de Manual Memory Management se ve así con ARC:

@interface MyObject : NSObject {
    NSString *_property;
}
@end

@implementation MyObject
@synthesize property = _property;

- (id)initWithProperty:(NSString *)property {
    if (self = [super init]) {
        _property = property;
    }
    return self;
}

- (NSString *)property {
    return property;
}

- (void)setProperty:(NSString *)property {
    _property = property;
}

@end
int main() {
    MyObject *obj = [[MyObject alloc] init];
    
    NSString *value = [[NSString alloc] initWithString:@"value"];
    [obj setProperty:value];

    [obj setProperty:@"value"];
}

Aún puede anular el método dealloc para limpiar los recursos no gestionados por ARC. A diferencia de cuando se usa la administración de memoria manual, no se llama [super dealloc] .

-(void)dealloc {
   //clean up
}

Referencias fuertes y débiles.

Moderno

Una referencia débil se parece a una de estas:

@property (weak) NSString *property;
NSString *__weak variable;

Si tiene una referencia débil a un objeto, entonces bajo el capó:

  • No lo estás reteniendo.
  • Cuando se desasigna, cada referencia se establecerá automáticamente en nil

Las referencias a objetos son siempre fuertes por defecto. Pero puedes especificar explícitamente que son fuertes:

@property (strong) NSString *property;
NSString *__strong variable;

Una referencia fuerte significa que mientras exista esa referencia, está reteniendo el objeto.

Gestión de memoria manual

Este es un ejemplo de un programa escrito con administración de memoria manual. Realmente no deberías escribir tu código de esta manera, a menos que por alguna razón no puedas usar ARC (como si necesitas soportar 32 bits). El ejemplo evita la notación de @property para ilustrar cómo solía tener que escribir getters y setters.

@interface MyObject : NSObject {
    NSString *_property;
}
@end

@implementation MyObject
@synthesize property = _property;

- (id)initWithProperty:(NSString *)property {
    if (self = [super init]) {
        // Grab a reference to property to make sure it doesn't go away.
        // The reference is released in dealloc.
        _property = [property retain];
    }
    return self;
}

- (NSString *)property {
    return [[property retain] autorelease];
}

- (void)setProperty:(NSString *)property {
    // Retain, then release. So setting it to the same value won't lose the reference.
    [property retain];
    [_property release];
    _property = property;
}

- (void)dealloc {
    [_property release];
    [super dealloc]; // Don't forget!
}

@end
int main() {
    // create object
    // obj is a reference that we need to release
    MyObject *obj = [[MyObject alloc] init];
    
    // We have to release value because we created it.
    NSString *value = [[NSString alloc] initWithString:@"value"];
    [obj setProperty:value];
    [value release];

    // However, string constants never need to be released.
    [obj setProperty:@"value"];
    [obj release];
}

Reglas de gestión de memoria cuando se utiliza el conteo manual de referencias.

Estas reglas solo se aplican si utiliza el recuento manual de referencias

  1. Eres dueño de cualquier objeto que crees

    Al llamar a un método cuyo nombre comienza con alloc , new , copy o mutableCopy . Por ejemplo:

    NSObject *object1 = [[NSObject alloc] init];
    NSObject *object2 = [NSObject new];
    NSObject *object3 = [object2 copy];
    

    Eso significa que usted es responsable de liberar estos objetos cuando haya terminado con ellos.

  2. Puedes tomar posesión de un objeto usando retener

    Para tomar posesión de un objeto, se llama el método de retención.

    Por ejemplo:

    NSObject *object = [NSObject new]; // object already has a retain count of 1
    [object retain]; // retain count is now 2
    

    Esto solo tiene sentido en algunas situaciones raras.

    Por ejemplo, cuando implementas un descriptor de acceso o un método init para tomar posesión:

    - (void)setStringValue:(NSString *)stringValue {
        [_privateStringValue release]; // Release the old value, you no longer need it
        [stringValue retain]; // You make sure that this object does not get deallocated outside of your scope.
        _privateStringValue = stringValue;
    }
    
  3. Cuando ya no lo necesite, debe renunciar a la propiedad de un objeto que posee

    NSObject* object = [NSObject new]; // The retain count is now 1
    [object performAction1]; // Now we are done with the object
    [object release]; // Release the object
    
  4. No debe renunciar a la propiedad de un objeto que no posee

    Eso significa que cuando no te apropiaste de un objeto, no lo liberas.

  5. Autoreleasepool

    El autoreleasepool es un bloque de código que libera cada objeto en el bloque que recibió un mensaje de autorelease.

    Ejemplo:

    @autoreleasepool {
        NSString* string = [NSString stringWithString:@"We don't own this object"];
    }
    

    Hemos creado una cadena sin tomar posesión. El NSString método stringWithString: tiene que asegurarse de que la cadena se desasigna correctamente después de que ya no es necesaria. Antes de que el método devuelva la cadena recién creada, se llama al método autorelease para que no tenga que tomar posesión de la cadena.

    Así es como se implementa el stringWithString: :

    + (NSString *)stringWithString:(NSString *)string {
        NSString *createdString = [[NSString alloc] initWithString:string];
        [createdString autorelease];
        return createdString;
    }
    

    Es necesario usar bloques de autoreleasepool porque a veces tienes objetos que no tienes (las cuartas reglas no siempre se aplican).

    El conteo automático de referencias cuida automáticamente las reglas para que no tenga que hacerlo.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow