2010-12-02 12 views
0

Je pense qu'il y a quelque chose que je n'ai pas compris dans la gestion de la mémoire dans xcode et quand libérer ou non des objets pour éviter les fuites de mémoire. Je suis en train de lire cette présentation, mais comme il n'y a pas de son je ne comprends pas tous les côtés: http://www.slideshare.net/OwenGoss/finding-and-fixing-memory-leaks-in-ios-apps-5251292L'envoi de release après [[NSString alloc] init] provoque EXIT_BAD_ACCESS

Voici un code très simple de mon application qui est la question:

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

NSString *myBundleName = [[NSString alloc] init]; 
NSString *myBundleVersion = [[NSString alloc] init]; 
NSString *myBundleBuild = [[NSString alloc] init]; 
NSString *myIosName = [[NSString alloc] init]; 
NSString *myIosVersion = [[NSString alloc] init]; 

myBundleName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"]; 
myBundleVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; 
myBundleBuild = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]; 
myIosName = [[UIDevice currentDevice] systemName ]; 
myIosVersion = [[UIDevice currentDevice] systemVersion]; 

self.versionBuildLabel.text = [NSString stringWithFormat:@"%@ version %@ build %@ on %@ %@", myBundleName, myBundleVersion, myBundleBuild, myIosName, myIosVersion]; 

[myBundleName release]; 
[myBundleVersion release]; 
[myBundleBuild release]; 
[myIosName release]; 
[myIosVersion release]; 

} 

Si je tente de exécuter ce

[myBundleName release]; 
[myBundleVersion release]; 
[myBundleBuild release]; 
[myIosName release]; 
[myIosVersion release]; 

Puis l'application se bloque avec

[Session started at 2010-12-02 14:08:47 +0700.] 
GNU gdb 6.3.50-20050815 (Apple version gdb-1472) (Wed Jul 21 10:53:12 UTC 2010) 
Copyright 2004 Free Software Foundation, Inc. 
GDB is free software, covered by the GNU General Public License, and you are 
welcome to change it and/or distribute copies of it under certain conditions. 
Type "show copying" to see the conditions. 
There is absolutely no warranty for GDB. Type "show warranty" for details. 
This GDB was configured as "x86_64-apple-darwin". 
sharedlibrary apply-load-rules all 
Attaching to process 26707. 
Pending breakpoint 1 - ""HomeVC.m":49" resolved 
(gdb) continue 
Current language: auto; currently objective-c 
[Switching to process 26707] 
[Switching to process 26707] 
Program received signal: “EXC_BAD_ACCESS”. 
(gdb) 

Je pensais que je faisais la bonne chose en libérant des variables intermédiaires utilisées pour rendre mon code plus facile à comprendre.

Quel est le problème ici? NB: Je rencontre des problèmes similaires dans d'autres parties de mon code, mais c'est l'exemple le plus simple qui me pose des problèmes, pour lesquels il y a probablement une notion que je n'ai pas comprise.

Répondre

4

Lorsque vous affectez vos variables avec des éléments de [UIDevice currentDevice] et [NSBundle mainBundle], ces objets sont auto-libérés. Depuis qu'ils sont autoreleased, iOS gère automatiquement la gestion de la mémoire de ces objets pour vous. C'est pourquoi votre application se bloque lorsque vous tentez de les supprimer manuellement.

N'initialisez pas vos NSString à de nouveaux objets (par exemple, [[NSString alloc] init]). initialisez avec les méthodes pratiques tout de suite:

NSString *myBundleName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"]; 
NSString *myBundleVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; 
NSString *myBundleBuild = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]; 
NSString *myIosName = [[UIDevice currentDevice] systemName]; 
NSString *myIosVersion = [[UIDevice currentDevice] systemVersion]; 

Et ne pas appeler release sur l'un d'eux. De cette façon, votre méthode n'a jamais la propriété de ces objets; ils viennent juste d'être passé à l'utiliser.

+0

Je pense que je l'ai compris: je ne devrais libérer des variables que si je leur attribue une valeur comme @ "Foo"? – ceyquem

+0

@ceyquem: Vous libérez des variables si vous les obtenez à partir de méthodes telles que 'init',' copy', 'retain' et' new'. Le littéral 'NSString'' @ "Foo" 'est en fait un objet constant qui n'est pas auto-libéré, mais vous le traitez de la même façon que vous n'appelez pas manuellement la version. – BoltClock