Recherche…


Comptage automatique des références

Avec le comptage automatique des références (ARC), le compilateur insère des instructions de retain , de release et d’ autorelease lorsque cela est nécessaire, ce qui vous autorelease de les écrire vous-même. Il écrit également des méthodes de dealloc pour vous.

Le programme exemple de Manual Memory Management ressemble à ceci avec 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"];
}

Vous pouvez toujours remplacer la méthode dealloc pour nettoyer les ressources non gérées par ARC. Contrairement à l'utilisation de la gestion manuelle de la mémoire, vous n'appelez pas [super dealloc] .

-(void)dealloc {
   //clean up
}

Références fortes et faibles

Moderne

Une référence faible ressemble à l'une de ces:

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

Si vous avez une référence faible à un objet, alors sous le capot:

  • Vous ne le retenez pas.
  • Quand il est désalloué, chaque référence sera automatiquement mise à nil

Les références d'objet sont toujours fortes par défaut. Mais vous pouvez explicitement spécifier qu'ils sont forts:

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

Une référence forte signifie que, même si cette référence existe, vous conservez l'objet.

Gestion de la mémoire manuelle

Voici un exemple de programme écrit avec gestion manuelle de la mémoire. Vous ne devriez vraiment pas écrire votre code comme celui-ci, à moins que vous ne puissiez pas utiliser ARC (comme si vous deviez prendre en charge 32 bits). L'exemple évite la notation @property pour illustrer comment vous deviez écrire des getters et des setters.

@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];
}

Règles de gestion de la mémoire lors de l'utilisation du comptage manuel des références.

Ces règles s'appliquent uniquement si vous utilisez le comptage manuel des références!

  1. Vous possédez un objet que vous créez

    En appelant une méthode dont le nom commence par alloc , new , copy ou mutableCopy . Par exemple:

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

    Cela signifie que vous êtes responsable de la libération de ces objets lorsque vous en avez fini avec eux.

  2. Vous pouvez prendre possession d'un objet à l'aide de keep

    Pour prendre possession d'un objet que vous appelez la méthode de conservation.

    Par exemple:

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

    Cela n'a de sens que dans certaines situations rares.

    Par exemple, lorsque vous implémentez un accesseur ou une méthode init pour prendre possession:

    - (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. Lorsque vous n'en avez plus besoin, vous devez renoncer à la propriété d'un objet que vous possédez.

    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. Vous ne devez pas renoncer à la propriété d'un objet que vous ne possédez pas

    Cela signifie que lorsque vous n'avez pas pris possession d'un objet, vous ne le libérez pas.

  5. Autoreleasepool

    Le pool d'autorélease est un bloc de code qui libère tous les objets du bloc qui ont reçu un message d'autorisation automatique.

    Exemple:

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

    Nous avons créé une chaîne sans en prendre possession. La méthode NSString stringWithString: doit s'assurer que la chaîne est correctement désallouée une fois qu'elle n'est plus nécessaire. Avant que la méthode ne retourne, la chaîne nouvellement créée appelle la méthode autorelease pour qu'il ne soit pas nécessaire qu'elle prenne possession de la chaîne.

    Voici comment la stringWithString: est implémentée:

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

    Il est nécessaire d'utiliser les blocs autoreleasepool car vous avez parfois des objets que vous ne possédez pas (la quatrième règle ne s'applique pas toujours).

    Le comptage automatique des références prend automatiquement en charge les règles afin que vous n'ayez pas à le faire.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow