Domanda

Domanda stupida, ma perché abbiamo bisogno di utilizzo di 'trattenere' quando la dichiarazione di una proprietà?Non avere mantenuto in ogni caso quando si è ricevuto qualcosa?

Guardando a questo esempio, sembra che un oggetto viene automaticamente mantenuta quando alloc sotto, così che cosa è il punto?

#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

■uscita

Frazione 1 retain count:1

Frazione 2 retain count:1

Frazione 1 retain count:3

Frazione 2 retain count:2

Frazione 1 retain count:2

Frazione 2 retain count:1

Deallocing frazione

Deallocing frazione


Questo mi sta facendo impazzire!

È stato utile?

Soluzione

Il comportamento predefinito della proprietà è di ASSEGNARE, non CONSERVARE.Questi non sono lo stesso comportamento.Se la vostra proprietà è per un tipo di dati di base, come un int, quindi ASSEGNARE sarebbe corretto utilizzare.Tuttavia, se si specifica (mantenere) e la proprietà punta a un puntatore all'oggetto come NSObject *l'oggetto, il puntatore viene assegnato l'indirizzo di memoria dell'oggetto e mantenere il conteggio viene incrementato di uno.Se il programma si compone di niente di più che una singola funzione principale, quindi si fa fatica a vedere.Tuttavia, si supponga che la classe ha avuto questo metodo:

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

Supponiamo myArray è definito come NSArray *myArray e ha la corretta @property (mantenere) istruzione.Tutto funziona bene fino a quando il metodo restituisce.Questo perché l'oggetto restituito da NSArray è un autoreleased oggetto.Se noi non lo si possiede, sarà rilasciato entro la NSAutoReleasePool e non saremo in grado di usarlo (e ci arriveremo un bug di brutto e il cattivo violazioni di accesso).Per risolvere questo problema è possibile fare due cose:

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

La prima soluzione, che usa l'auto.myArray di utilizzare il @definizione di proprietà.Questo codice assegna e conserva quindi l'oggetto in modo da non perdere quando la funzione restituisce.La seconda soluzione imposta il NSArray *myArray puntatore manualmente manualmente e poi mantiene il NSArray oggetto.In entrambi i casi l'NSAutoreleasePool rilascerà l'oggetto alla fine della funzione, tuttavia non essere deallocato perché abbiamo ancora il nostro trattenere dal precedente mantenere viva.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top