2010-11-19 23 views
2

J'ai lu sur autoreleasepool mais il y a un point qui est un peu clair pour moi. J'ai une certaine fonctionnalité en utilisant des threads qui nécessitent une gestion séparée de la mémoire en utilisant autoreleasepool.iPhone Autoreleasepool et allocations

Dans l'exemple suivant est correct

-(void) doSomething { 

    NSAutorelease *pool = [[NSAutorelasepool alloc] init]; 

    NSString *myString = @"Hello"; 

    [pool release]; 
} 

Est-ce exact?

-(void) doSomething { 

    NSAutorelease *pool = [[NSAutorelasepool alloc] init]; 

    NSString *myString = [[NSString alloc] initWithString:@"Hello"]; 

    [pool release]; 
} 

ou cela?

-(void) doSomething { 

    NSAutorelease *pool = [[NSAutorelasepool alloc] init]; 

    NSString *myString = [[NSString alloc] initWithString:@"Hello"]; 

    [myString release]; 
    [pool release]; 
} 

Ma question est des objets appartenant créés dans le cadre de la piscine autorelease ont besoin d'être relased spécifiquement ou sont les Soigné lorsque le autorelasepool est été libéré?

Teo

Répondre

1

Le pool de libération automatique gère les objets auto-libérés. Si vous possédez un objet (via alloc ou copy ou retain), vous devez le libérer. Donc votre 2ème exemple n'est pas correct. Comme vous avez attribué la chaîne, vous la possédez et vous devez la libérer.

Un pool de libération automatique est créé pour le thread principal. (Vous pouvez regarder dans la fonction principale si vous voulez). Chaque thread a besoin de son propre pool de libération automatique pour gérer les objets auto-libérés. C'est pourquoi si vous créez un autre thread, vous devez créer un pool autorelease pour ce thread. Même si vous ne créez pas d'objet autoreleased dans le thread, vous devez le créer car les appels de bibliothèque dans ce thread peuvent créer des objets auto-libérés.Même si vous êtes sûr qu'aucun appel de bibliothèque ne crée des objets autoreleased, vous devez également les créer car c'est la meilleure pratique, spécialement si vous travaillez sur un gros projet qui est développé et maintenu par plusieurs personnes.

0

Il vous suffit de créer votre propre piscine autorelease lorsque vous créez un groupe d'objets autoreleased vous voulez ordures immédiatement recueillir. Cependant, vous avez raison de ne pas référencer les objets "autoreleased" que vous créez après la libération du pool. Les objets libérés (que vous ne conservez pas) sont détruits lorsque le pool est vidé.

Puisqu'aucun des objets de votre exemple n'est auto-libéré, la création de votre propre pool de libération automatique est essentiellement un no-op.

+0

En fait, il parle de fil. Donc, le pool d'autorelease est nécessaire. – taskinoor

+0

Pour quoi, s'il ne crée pas d'objets autoreleased? – zoul

+0

@zoul, s'il vous plaît vérifier la dernière partie de ma réponse. Même si vous n'êtes pas d'accord, je préférerais suivre les meilleures pratiques. – taskinoor

0

Aucun de vos exemples n'a besoin d'un pool d'autorelease. piscines autorelease ne prennent soin des objets autoreleased:

NSArray *foo = [NSArray array]; 
NSObject *bar = [[[NSObject alloc] init] autorelease]; 

Votre première chaîne est initialisé à l'aide d'une chaîne littérale et est donc probablement particulière en ce qui concerne la gestion de la mémoire (peut-être quelqu'un d'autre sait plus). Votre deuxième corde fuit, la piscine ne fait pas de différence. Votre troisième chaîne est libérée correctement, encore une fois le pool ne fait pas de différence.

C'est là que vous avez besoin d'une piscine:

- (void) someMethodThatRunsOnAThread { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSString *foo = [@"foo" uppercaseString]; 
    [pool drain]; 
} 

Voici la chaîne foo fuirait si la piscine était pas là. Notez que j'appelle drain au lieu de release sur le pool - sur iOS, il n'y a pas de différence, mais dans les environnements récupérés, les deux sont différents, donc il est probablement préférable de prendre l'habitude d'appeler le bon. Notez également que vous pouvez avoir besoin d'un pool, même si vous ne libérez pas automatiquement les objets vous-même, il peut y avoir de nombreuses opérations de mémoire effectuées quelque part dans le code que vous appelez dans votre méthode.

+0

En fait, il parle de fil. Je suppose que les méthodes d'exemple s'exécutent sur un thread séparé. – taskinoor

+0

Vous n'avez pas besoin d'un pool d'autorelease sur un thread si vous ne créez aucun objet autoreleased. – zoul

+0

s'il vous plaît vérifier la dernière partie de ma réponse. Même si vous n'êtes pas d'accord, je préférerais suivre les meilleures pratiques. – taskinoor

0

pense que ce devrait être quelque chose comme ceci:

-(void) doSomething { 

    NSAutorelease *pool = [[NSAutorelasepool alloc] init]; 


    NSString *myString = [[[NSString alloc] initWithString:@"Hello"] autorelease]; 

    // or create string like this (automatically autoreleased) 
    NSString *myString = [NSString stringWithString:@"Hello"]; 

    [pool release]; 
} 

Vous devez envoyer un message autorelease, à des objets à l'intérieur de la piscine autorelease. Ils seront publiés lorsque le message de libération sera envoyé au pool.

+0

Ne relâchez-vous pas le pool en envoyant '-drain' et' -release'? – zoul

+0

oups ... oui ... :) – marko