Pergunta

Pergunta estúpida, mas por que precisamos usar 'retain' ao declarar um imóvel?Ele não é retido de qualquer maneira quando algo é atribuído?

Olhando para este exemplo, parece que um objeto é retido automaticamente quando alocado, então qual é o sentido?

#import "Fraction.h"
#import <stdio.h>

int main( int argc, const char *argv[] ) {
    Fraction *frac1 = [[Fraction alloc] init];
    Fraction *frac2 = [[Fraction alloc] init];

    // print current counts
    printf( "Fraction 1 retain count: %i\n", [frac1 retainCount] );
    printf( "Fraction 2 retain count: %i\n", [frac2 retainCount] );

    // increment them
    [frac1 retain]; // 2
    [frac1 retain]; // 3
    [frac2 retain]; // 2

    // print current counts
    printf( "Fraction 1 retain count: %i\n", [frac1 retainCount] );
    printf( "Fraction 2 retain count: %i\n", [frac2 retainCount] );

    // decrement
    [frac1 release]; // 2
    [frac2 release]; // 1

    // print current counts
    printf( "Fraction 1 retain count: %i\n", [frac1 retainCount] );
    printf( "Fraction 2 retain count: %i\n", [frac2 retainCount] );

    // release them until they dealloc themselves
    [frac1 release]; // 1
    [frac1 release]; // 0
    [frac2 release]; // 0

■saída

A fração 1 retém a contagem:1

A fração 2 retém a contagem:1

A fração 1 retém a contagem:3

A fração 2 retém a contagem:2

A fração 1 retém a contagem:2

A fração 2 retém a contagem:1

Fração de desalocação

Fração de desalocação


Isto está me enlouquecendo!

Foi útil?

Solução

O comportamento padrão de uma propriedade é ASSIGN, não RETAIN.Estes não são o mesmo comportamento.Se sua propriedade for para um tipo de dados primitivo, como int, então ASSIGN seria correto para uso.No entanto, se você especificar (reter) e a propriedade apontar para um ponteiro de objeto como NSObject *object, o ponteiro receberá o endereço de memória do objeto e sua contagem de retenção será incrementada em um.Se o seu programa consiste em nada mais do que uma função principal isolada, então é difícil ver seu propósito.No entanto, suponha que sua classe tenha este método:

-(void)setMyArrayWithString:(NSString *)s{
    myArray = [NSArray arrayWithObject:s];
    }

Suponha que myArray seja definido como NSArray *myArray e tenha a instrução @property (retain) adequada.Tudo funciona bem até o método retornar.Isso ocorre porque o objeto retornado do NSArray é um objeto liberado automaticamente.Se não o mantivermos, ele será liberado pelo NSAutoReleasePool e não poderemos usá-lo (e teremos bugs desagradáveis ​​e violações de acesso incorretas).Para corrigir isso, podemos fazer uma de duas coisas:

-(void)setMyArrayWithString:(NSString *)s{
    self.myArray = [NSArray arrayWithObject:s];
// OR
    myArray = [[NSArray arrayWithObject:s] retain];    
}

A primeira solução usa self.myArray para utilizar a definição @property.Este código atribui e retém o objeto para que não o percamos quando a função retornar.A segunda solução define o ponteiro NSArray *myArray manualmente e, em seguida, retém manualmente o objeto NSArray.De qualquer forma, o NSAutoreleasePool liberará o objeto no final da função, porém ele não será desalocado porque ainda temos a chance de mantê-lo ativo anteriormente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top