Ricerca…


Conteggio di riferimento automatico

Con il conteggio dei riferimenti automatico (ARC), il compilatore inserisce le istruzioni di retain , release e autorelease laddove sono necessarie, quindi non è necessario scriverle da soli. Scrive anche metodi dealloc per te.

Il programma di esempio di Gestione memoria manuale ha questo aspetto con ARC:

@interface MyObject : NSObject {
    NSString *_property;
}
@end

@implementation MyObject
@synthesize property = _property;

- (id)initWithProperty:(NSString *)property {
    if (self = [super init]) {
        _property = property;
    }
    return self;
}

- (NSString *)property {
    return property;
}

- (void)setProperty:(NSString *)property {
    _property = property;
}

@end
int main() {
    MyObject *obj = [[MyObject alloc] init];
    
    NSString *value = [[NSString alloc] initWithString:@"value"];
    [obj setProperty:value];

    [obj setProperty:@"value"];
}

Sei ancora in grado di sovrascrivere il metodo dealloc per ripulire le risorse non gestite da ARC. A differenza di quando si utilizza la gestione manuale della memoria, non si chiama [super dealloc] .

-(void)dealloc {
   //clean up
}

Riferimenti forti e deboli

Moderno

Un riferimento debole sembra uno di questi:

@property (weak) NSString *property;
NSString *__weak variable;

Se hai un riferimento debole a un oggetto, quindi sotto il cofano:

  • Non lo stai mantenendo.
  • Quando viene deallocato, ogni riferimento ad esso verrà automaticamente impostato su nil

I riferimenti agli oggetti sono sempre forti per impostazione predefinita. Ma puoi esplicitamente specificare che sono forti:

@property (strong) NSString *property;
NSString *__strong variable;

Un riferimento forte significa che mentre quel riferimento esiste, stai mantenendo l'oggetto.

Gestione manuale della memoria

Questo è un esempio di un programma scritto con gestione manuale della memoria. Non dovresti scrivere il tuo codice in questo modo, a meno che per qualche ragione non puoi usare ARC (come se dovessi supportare 32-bit). L'esempio evita la notazione @property per illustrare in che modo si doveva scrivere getter e setter.

@interface MyObject : NSObject {
    NSString *_property;
}
@end

@implementation MyObject
@synthesize property = _property;

- (id)initWithProperty:(NSString *)property {
    if (self = [super init]) {
        // Grab a reference to property to make sure it doesn't go away.
        // The reference is released in dealloc.
        _property = [property retain];
    }
    return self;
}

- (NSString *)property {
    return [[property retain] autorelease];
}

- (void)setProperty:(NSString *)property {
    // Retain, then release. So setting it to the same value won't lose the reference.
    [property retain];
    [_property release];
    _property = property;
}

- (void)dealloc {
    [_property release];
    [super dealloc]; // Don't forget!
}

@end
int main() {
    // create object
    // obj is a reference that we need to release
    MyObject *obj = [[MyObject alloc] init];
    
    // We have to release value because we created it.
    NSString *value = [[NSString alloc] initWithString:@"value"];
    [obj setProperty:value];
    [value release];

    // However, string constants never need to be released.
    [obj setProperty:@"value"];
    [obj release];
}

Regole di gestione della memoria quando si utilizza il conteggio dei riferimenti manuale.

Queste regole si applicano solo se si utilizza il conteggio dei riferimenti manuale!

  1. Sei proprietario di qualsiasi oggetto che crei

    Chiamando un metodo il cui nome inizia con alloc , new , copy o mutableCopy . Per esempio:

    NSObject *object1 = [[NSObject alloc] init];
    NSObject *object2 = [NSObject new];
    NSObject *object3 = [object2 copy];
    

    Ciò significa che sei responsabile del rilascio di questi oggetti quando hai finito con loro.

  2. Puoi assumere la proprietà di un oggetto usando retain

    Per assumere la proprietà di un oggetto, si chiama il metodo retain.

    Per esempio:

    NSObject *object = [NSObject new]; // object already has a retain count of 1
    [object retain]; // retain count is now 2
    

    Questo ha senso solo in alcune rare situazioni.

    Ad esempio quando implementi un metodo di accesso o un metodo init per diventare proprietario:

    - (void)setStringValue:(NSString *)stringValue {
        [_privateStringValue release]; // Release the old value, you no longer need it
        [stringValue retain]; // You make sure that this object does not get deallocated outside of your scope.
        _privateStringValue = stringValue;
    }
    
  3. Quando non ne hai più bisogno, devi rinunciare alla proprietà di un oggetto che possiedi

    NSObject* object = [NSObject new]; // The retain count is now 1
    [object performAction1]; // Now we are done with the object
    [object release]; // Release the object
    
  4. Non devi rinunciare alla proprietà di un oggetto che non possiedi

    Ciò significa che quando non sei diventato proprietario di un oggetto non lo pubblichi.

  5. Autoreleasepool

    L'autoreleasepool è un blocco di codice che rilascia ogni oggetto nel blocco che ha ricevuto un messaggio di autorelease.

    Esempio:

    @autoreleasepool {
        NSString* string = [NSString stringWithString:@"We don't own this object"];
    }
    

    Abbiamo creato una stringa senza assumerne la proprietà. Il metodo NSString stringWithString: deve assicurarsi che la stringa sia correttamente deallocata dopo che non è più necessaria. Prima che il metodo restituisca la stringa appena creata chiama il metodo di autorelease in modo che non debba assumere la proprietà della stringa.

    Questo è il modo in cui stringWithString: è implementato:

    + (NSString *)stringWithString:(NSString *)string {
        NSString *createdString = [[NSString alloc] initWithString:string];
        [createdString autorelease];
        return createdString;
    }
    

    È necessario utilizzare i blocchi autoreleasepool perché a volte si hanno oggetti che non si possiedono (la quarta regola non si applica sempre).

    Il conteggio automatico dei riferimenti prende automaticamente cura delle regole, quindi non è necessario.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow