Pergunta sobre ios, objective-c – Um objeto associado será lançado automaticamente?

14

Nota: Esta outra questão parece relevante, mas não é:Quando um objeto associado é liberado?

Estou adicionando uma segunda descrição a umUIView exemplo da seguinte forma:

- (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);   
}

Se oUIView deallocs, a descrição associada 2 será desalocada? Existe alguma maneira de fazer isso acontecer automaticamente?

Sua resposta

4   a resposta
3

quaisquer objetos associados (que usam oRETAIN ouCOPY tipos de associação) são liberados automaticamente.

0

Seção 4 de Jody Haginsresponda diz "Apagar referências associadas", o que não implica explicitamente que as referências são liberadas. Então usei o seguinte trecho de código (note SEM ARC) para testar isso.

@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 o código acima de fato acaba chamando - [AssociatedLibjectHelper dealloc], com o seguinte rastreamento de pilha:

#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]

Testado no Xcode 7.0.1

3

sim - quando o objeto proprietário é liberado, os objetos associados retidos são liberados. Veja a primeira seção da Appledocumentação

Obrigado @borrrden que ajuda. Dan Rosenstark
Eu vi essa seção. Onde diz que é lançado? Dan Rosenstark
@Yar claramente na segunda a última frase da primeira seção (Criando Associações): "Quando a matriz é desalocada, no entanto (no ponto 2), a visão geral é liberada e, nesse caso, também desalocada." :) borrrden
64

Vejo a descrição de toda a linha de tempo do dealloc, veja a WWDC 2011, Session 322, 36:22. No entanto, aqui está o resumo básico (eu queria lembrar, então este é um comentário real em um pedaço do meu código).

Observe que os objetos associados são liberados no final do 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()
+1 Isso é ótimo, Jody. Eu posso ter que assistir a sessão, já que não consigo entenderOnde esse código estaria localizado. Mas é mais a minha falta de compreensão de como a Obj-C é montada do que qualquer outra coisa. Dan Rosenstark
Essa é uma ótima informação, Jody, obrigado. Apenas gostaria de acrescentar que descobri que no iOS4, se você adicionar objetos associados a um objeto que também é registrado como um observador, os objetos associados nunca serão liberados mesmo que o objeto seja liberado. Portanto, usar o KVO em combinação com objetos associados no iOS4 interrompe essa cadeia de alguma forma. David
Quando a contagem de referência vai para 0, o objeto começa a morrer e esse caminho de código é executado. Existe alguma configuração para não permitir novas referências fracas e algumas outras coisas, e então a cadeia dealloc começa. Quando a cadeia dealloc é concluída, é quando todas as variáveis ​​de instância são destruídas (sob o ARC). Os objetos associados são apenas um mapa que é anexado junto com o resto do material (bem, costumava ser um std :: map <> - Eu não olhei ultimamente, mas eu realmente queria que eles usassem um array para pequenos números de objetos associados, depois use um mapa mais tarde - para limitar o consumo de memória). Jody Hagins

Perguntas relacionadas