2010-10-21 4 views
0

Je suis un peu perdu avec la gestion de la mémoire. J'ai lu que vous devriez libérer chaque fois que vous allouez. Mais quand vous obtenez une instance sans alloc, vous ne devriez pas libérer.Gestion de la mémoire IPhone

Qu'en est-il de cette situation, juste besoin de savoir Si je codais correctement. Je suis encore nouveau sur iphone dev.

J'ai une classe CustomerRepository il a une méthode

- (MSMutableArray *) GetAllCustomers() { 

    MSMutableArray *customers = [[MSMutableArray alloc] init]; 

    Customer *cust1 = [[Customer alloc] init]; 
    cust1.name = @"John"; 

    Customer *cust2 = [[Customer alloc] init]; 
    cust2.name = @"Tony"; 

    [customers addOjbect:cust1]; 
    [customers addOjbect:cust2]; 

    [cust1 release]; 
    [cust2 release]; 

    return customers; 

} 

J'ai un UIViewController

- (void) LoadCustomers() { 

     CustomerRepository *repo = [[CustomerRepository alloc] init]; 

     MSMutableArray *customers = [repo GetAllCustomers];   

     // Iterate through all customers and do something 

     [repo release]; 

} 

Donc, dans ce scénario ... le MSMutableArray ne sera jamais sortie? Où devrait-il être publié?

Répondre

6

Si vous attribuez un objet à une fonction dont vous avez besoin pour revenir de la fonction, vous ne pouvez pas le libérer dans la fonction. La manière correcte de faire ceci est de libérer automatiquement l'objet.

 
MSMutableArray *customers = [[MSMutableArray alloc] init]; 

// ..... do work 

return [customers autorelease]; 

C'est l'approche adoptée par les constructeurs de Connivence comme

 
[NSString stringWithString:@"test"]; 

Cette méthode vous renvoie une chaîne autoreleased afin que vous n'avez pas besoin de le libérer.

Et si vous ne le faites pas, vous devez nommer votre fonction en conséquence, l'appelant sait qu'il possède l'objet retourné et doit donc être libéré. Ce sont des conventions, pas une règle imposée par le compilateur ou l'environnement d'exécution, mais la convention suivante est extrêmement importante, spécialement quand plusieurs personnes sont impliquées dans le projet.

+0

J'ai lu quelque part que autorelease n'est pas trop bon pour être utilisé sur iphone. mais dans mon scénario, je n'ai vraiment pas d'autre choix que d'autorelease (c'est le ramassage des ordures correct)? Est-il préférable de renvoyer une autorelease dans ma méthode GetAllCustomers? Ou juste pour que le repo crée le tableau mais que la méthode LoadCustomer libère quand il en a fini? – pdiddy

+0

Ce que vous avez lu à propos de autorelease n'est certainement pas juste. Parcourez le guide de gestion de la mémoire d'Apple. Cela peut prendre un ou deux jours à lire, mais cela vous sauvera de beaucoup de désastre. Dans ce cas, autorelease dans la méthode GetAllCustomers, car le nom de la méthode n'implique pas que l'appelant sera propriétaire de l'objet retourné. – taskinoor

0

Le tableau de clients doit être libéré après l'avoir itéré. Vous avez délégué la création du tableau à votre objet repo, mais votre méthode LoadCustomers possède le tableau. Une autre approche serait d'exposer votre CustomerRepository à une propriété allCustomers. Vous pouvez paresseusement initialiser le tableau dans votre getter, puis libérer le tableau lorsque le CustomerRepository est libéré. Cela garderait vos appels à allouer et libérer dans le même objet.

0

il devrait être libéré dans votre contrôleur de vue, LoadCustomers() puisque vous allocing dans la méthode que vous appelez, il est encore propriété par vous.

2

Chaque fois que vous créez et renvoyez un objet à partir d'une méthode ou d'une fonction, cet objet doit être autorelease d. Les exceptions sont lorsque la méthode commence par Create ou New (ou Alloc, évidemment), ou lorsque l'objet est mis en cache dans la méthode.

Les autres réponses qui suggèrent le libérer dans LoadCustomers sont incorrects, car GetAllCustomers ne signifie pas un transfert de propriété comme CreateCustomersArray ou NewCustomersArray serait. Toutefois, vous ne pouvez pas libérer l'objet dans GetAllCustomers car l'objet serait alors désalloué avant de le renvoyer. La solution est autorelease.

+0

Bon point sur la dénomination de la méthode n'impliquant pas le transfert de propriété de l'objet. – highlycaffeinated

+0

Donc, ma seule option est d'utiliser autorelease correct – pdiddy

+0

Lorsque les méthodes commencent avec Create, comment transfère-t-il la propriété? – pdiddy