2010-06-08 6 views
0

im assez nouveau à l'objectif-c, la plupart de c'est clair cependant quand il s'agit de la gestion de la mémoire, je tombe un peu court. Actuellement, ce que mon application fait est lors d'un NSURLConnection lorsque la méthode -(void)connectionDidFinishLoading:(NSURLConnection *)connection est appelée Je saisis une méthode pour analyser certaines données, les placer dans un tableau et retourner ce tableau. Cependant je ne suis pas sûr si c'est la meilleure manière de faire puisque je ne libère pas le tableau de la mémoire dans la méthode personnalisée (méthode1, voir le code joint)tableau conserve la question

Voici un petit script pour mieux montrer ce que im faire

fichier .h

#import <UIKit/UIKit.h> 

@interface memoryRetainTestViewController : UIViewController { 

    NSArray *mainArray; 

} 

@property (nonatomic, retain) NSArray *mainArray; 

@end 

fichier .m

#import "memoryRetainTestViewController.h" 

@implementation memoryRetainTestViewController 
@synthesize mainArray; 


// this would be the parsing method 
-(NSArray*)method1 
{ 
    // ???: by not release this, is that bad. Or does it get released with mainArray 
    NSArray *newArray = [[NSArray alloc] init]; 
    newArray = [NSArray arrayWithObjects:@"apple",@"orange", @"grapes", "peach", nil]; 

    return newArray; 
} 


// this method is actually 
// -(void)connectionDidFinishLoading:(NSURLConnection *)connection 
-(void)method2 
{ 
    mainArray = [self method1]; 
} 

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 
- (void)viewDidLoad { 
    [super viewDidLoad]; 
} 

- (void)didReceiveMemoryWarning { 
    // Releases the view if it doesn't have a superview. 
    [super didReceiveMemoryWarning]; 

    // Release any cached data, images, etc that aren't in use. 
} 

- (void)viewDidUnload { 
    mainArray = nil; 
    // Release any retained subviews of the main view. 
    // e.g. self.myOutlet = nil; 
} 

- (void)dealloc { 
    [mainArray release]; 
    [super dealloc]; 
} 


@end 
+0

par la façon si vous avez juste __ [[NSArray alloc] init] __ l'élément n'est pas retenu ni autoreleased. Donc, il ne sera pas fuite de mémoire, il sera juste sorti à un moment hors de la portée de la fonction. Alors que si vous utilisez __ [NSArray array withObjects: ..] __ il sera facilement autoeleased et vous n'aurez pas besoin de le libérer sur dealloc. – Jack

+0

@Jack: C'est un non-sens, vous possédez les objets créés par '-alloc'. En outre, assigner des objets auto-libérés à ivars est mauvais, ils seront libérés quand le pool autorelease actuel est drainé, pas quand la durée de vie de votre objet se termine. Vous avez certainement des choses mélangées au sujet du comptage manuel et de la libération automatique, je vous recommande de lire le Guide de gestion de la mémoire. –

Répondre

2

Votre -method1 crée d'abord un nouveau tableau et écrasera avec un nouveau:

NSArray *newArray = [[NSArray alloc] init]; // first array, retained 
newArray = [NSArray arrayWithObjects:...]; // second array, auto-released, 
              // pointer to first one lost 

Le premier tableau est simplement divulgué ici. Vous fuyez également le tableau stocké dans l'ivar, utilisez simplement le setter synthétisé pour éviter cela - il retient et libère pour vous.

Si vous ne l'avez pas encore fait, lisez le Memory Management Guide pour Cocoa.

Une meilleure version:

- (NSArray *)method1 { 
    NSArray *newArray = [NSArray arrayWithObjects:...];  
    return newArray; 
} 

- (void)method2 { 
    self.mainArray = [self method1]; 
} 
+0

Merci, bien expliqué. – cdnicoll

2

Oui, votre newArray est libérée lorsque mainArray est libéré. Mais ceci juste si method2 est appelé une fois.

Nous parlons des références donc si vous avez

newArray = something 
mainArray = newArray 
[mainArray release] 

les deux variables seront juste un référencent NSArray*. Ensuite, dans votre cas newArray est juste un local donc il n'y a pas de problème.

Le problème se produit si vous appelez deux fois method2:

newArray = something 
mainArray = newArray 
newArray = something2 
mainArray = newArray <- old reference is lost 
[mainArray release] <- just something2 is released 

Pour éviter ce problème, vous devez vous assurer de libérer mainArray avant de remplacer la référence avec un autre objet.

EDIT: n'a pas remarqué que vous étiez en train de créer le tableau deux fois :) Non, ce n'est pas bon ..

+0

Ya ... une partie de ceci revient à l'adressage et à des pointeurs dans ma classe C++ du dernier semestre heh. Merci pour les conseils et l'aide. – cdnicoll