Pregunta sobre ios, objective-c – ¿Se lanzará un objeto asociado automáticamente?

14

Nota: esta otra pregunta parece relevante pero no lo es:¿Cuándo se libera un objeto asociado?

Estoy agregando una segunda descripción a unaUIView instancia de la siguiente manera:

- (void) setSecondDescription:(UIView*)view description2:(NSString*)description2 {
    objc_setAssociatedObject (view,&key,description2,OBJC_ASSOCIATION_RETAIN);
}

- (NSString*) secondDescription:(UIView*)view {
    return (id)objc_getAssociatedObject(view, &key);   
}

Si elUIView deallocs, ¿será desasignada la descripción asociada 2? ¿Hay alguna manera de conseguir que esto suceda automáticamente?

Tu respuesta

4   la respuesta
64

Si quieres en realidadver Para ver la descripción de toda la línea de tiempo de Dealloc, consulte WWDC 2011, Session 322, 36:22. Sin embargo, aquí está el resumen básico (quería recordarlo, así que este es un comentario real en una parte de mi código).

Tenga en cuenta que los objetos asociados se liberan al final del ciclo de vida.

// General Information
// We take advantage of the documented Deallocation Timeline (WWDC 2011, Session 322, 36:22).
// 1. -release to zero
//     * Object is now deallocating and will die.
//     * New __weak references are not allowed, and will get nil.
//     * [self dealloc] is called
// 2. Subclass -dealloc
//     * bottom-most subclass -dealloc is called
//     * Non-ARC code manually releases iVars
//     * Walk the super-class chain calling -dealloc
// 3. NSObject -dealloc
//     * Simply calls the ObjC runtime object_dispose()
// 4. object_dispose()
//     * Call destructors for C++ iVars
//     * Call -release for ARC iVars
//     * Erase associated references
//     * Erase __weak references
//     * Call free()
Cuando el recuento de referencias llega a 0, el objeto comienza a morir y se ejecuta esta ruta de código. Existe alguna configuración para no permitir nuevas referencias débiles, y algunas otras cosas, y luego comienza la cadena de dealloc. Cuando se realiza la cadena de dealloc, es cuando se destruyen todas las variables de instancia (bajo ARC). Los objetos asociados son solo un mapa que se adjunta junto con el resto de las cosas (bueno, solía ser un std :: map <> - No he mirado últimamente, pero realmente quería que usaran una matriz para pequeños números de objetos asociados, luego use un mapa más adelante (para limitar el consumo de memoria). Jody Hagins
Esta es una gran pieza de información Jody, gracias. Al igual que para agregar, descubrí que en iOS4, si agrega objetos asociados a un objeto que también está registrado como observador, los objetos asociados nunca se liberarán aunque el objeto se libere. Entonces, usar KVO en combinación con objetos asociados en iOS4 rompe esta cadena de alguna manera. David
+1 Esto es genial, Jody. Puede que tenga que ver la sesión, ya que no puedo entender.dónde este código estaría ubicado. Pero eso es más mi falta de comprensión de cómo se forma el Obj-C que cualquier otra cosa. Dan Rosenstark
3

Sí. Cuando se desasigna un objeto, cualquier objeto asociado (que use elRETAIN oCOPY tipos de asociación) se liberan automáticamente.

0

Sección 4 en Jody Haginsresponder dice "Borrar referencias asociadas", lo que no implica explícitamente que las referencias se liberen. Así que utilicé el siguiente código (nota SIN ARCO) para probar esto.

@interface AssociatedObjectHelper : NSObject
@end

@implementation AssociatedObjectHelper
- (void) dealloc
{
    NSLog(@"In %s", __FUNCTION__);
    [super dealloc];
}
@end

@implementation AppDelegate
...
- (void) testReleaseAssociatedObject
{
    static const NSString *key = @"testKey123";
    NSObject *ob = [NSObject new];
    AssociatedObjectHelper *assocOb = [AssociatedObjectHelper new];
    objc_setAssociatedObject(ob, key, assocOb, OBJC_ASSOCIATION_RETAIN);
    [assocOb release];
    [ob release];
}

Invocar el código anterior de hecho termina llamando - [AssociatedObjectHelper dealloc], con el siguiente seguimiento de pila:

#0  0x000000010000528f in -[AssociatedObjectHelper dealloc]
#1  0x00007fff8a0bb89c in objc_object::sidetable_release(bool) ()
#2  0x00007fff8a0a537f in _object_remove_assocations ()
#3  0x00007fff8a0a1644 in objc_destructInstance ()
#4  0x00007fff8a0a1595 in object_dispose ()
#5  0x00007fff8a0bb89c in objc_object::sidetable_release(bool) ()
#6  0x000000010000e9b6 in -[AppDelegate testReleaseAssociatedObject]

Probado en Xcode 7.0.1

3

En resumen, sí: cuando se libera el objeto propietario, se liberan los objetos asociados retenidos. Vea la primera sección de Appledocumentación

Gracias @borrrden que ayuda. Dan Rosenstark
He visto esa sección. ¿Dónde dice que está lanzado? Dan Rosenstark
@Yar claramente en la segunda a la última oración de la primera sección (Creación de asociaciones): "Sin embargo, cuando la matriz se desasigna (en el punto 2), se publica el resumen y, en este caso, también se desasigna". :) borrrden

Preguntas relacionadas