Frage

Dumme Frage, aber warum müssen wir beim Deklarieren einer Immobilie "Rückhalt" verwenden? Wird es nicht sowieso beibehalten, wenn es etwas zugewiesen hat?

Wenn man sich dieses Beispiel ansieht, scheint es, dass ein Objekt beim Alloc automatisch aufbewahrt wird. Was ist also der Punkt?

#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

■ Ausgabe

BRAKT 1 Halten Sie die Anzahl: 1

BRAKT 2 Halten Sie Graf: 1

BRAKT 1 Halten Sie Graf: 3

BRAKT 2 Halten Sie Graf: 2

BRAKT 1 Halten Sie die Anzahl: 2

BRAKT 2 Halten Sie Graf: 1

Bruchbruchung

Bruchbruchung


Das macht mich verrückt!

War es hilfreich?

Lösung

Das Standardverhalten einer Eigenschaft wird zugewiesen, nicht behalten. Dies sind nicht das gleiche Verhalten. Wenn Ihre Eigenschaft für einen primitiven Datentyp wie eine INT gilt, wäre die Zuweisung korrekt. Wenn Sie jedoch ein Objektzeiger wie das NSObject *-Objekt angeben (behalten), wird dem Zeiger die Speicheradresse des Objekts zugeordnet und die Anzahl wird von einem erhöht. Wenn Ihr Programm nur aus einer einzigen Hauptfunktion besteht, ist es schwer zu erkennen. Angenommen, Ihre Klasse hatte diese Methode:

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

Angenommen, MyArray ist definiert als NSArray *Myarray und hat die richtige @Property (Retain) -serklärung. Alles funktioniert gut, bis die Methode zurückkehrt. Dies liegt daran, dass das von NSArray zurückgegebene Objekt ein autoreleaes Objekt ist. Wenn wir es nicht behalten, wird es von der NSAutoreleaSepool veröffentlicht und wir werden es nicht verwenden (und wir werden böse Fehler und schlechte Zugriffsverletzungen bekommen). Um dies zu beheben, können wir eines von zwei Dingen tun:

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

Die erste Lösung verwendet Self.MyArray, um die @Property -Definition zu verwenden. Dieser Code weist das Objekt zu und behält dann, damit wir es nicht verlieren, wenn die Funktion zurückgibt. Die zweite Lösung setzt den NSArray *Myarray -Zeiger manuell und behält dann das NSArray -Objekt manuell bei. In beiden Fällen wird der NSAutoreleasepool das Objekt am Ende der Funktion freigeben, es wird jedoch nicht verhandelt, da wir immer noch davon abhalten, es am Leben zu erhalten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top