2010-12-02 6 views
0

Ich denke, es gibt etwas, das ich nicht in der Speicherverwaltung in xcode und wann zu lösen oder nicht, um Objekte zu vermeiden Speicherlecks zu verstehen. Ich habe diese Präsentation gelesen, aber da gibt es kein Audio Ich versteht alle Seiten nicht ist: http://www.slideshare.net/OwenGoss/finding-and-fixing-memory-leaks-in-ios-apps-5251292Senden von Release nach [[NSString Alloc] Init] verursacht EXIT_BAD_ACCESS

Hier ist ein sehr einfacher Code meiner app, dass das Problem ist:

// 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]; 

} 

Wenn ich versuche, führen Sie dieses

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

Dann stürzt die Anwendung mit

[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) 

Ich dachte, ich würde das Richtige tun, indem ich Zwischenvariablen freisetze, um meinen Code leichter verständlich zu machen.

Was ist das Problem hier?

NB: Ich habe ähnliche Probleme in anderen Teilen meines Codes, aber dies ist das einfachste Beispiel, das mir Probleme bereitet, für die es wahrscheinlich eine Vorstellung gibt, die ich nicht verstanden habe.

Antwort

4

Wenn Sie Ihre Variablen mit Elementen aus [UIDevice currentDevice] und [NSBundle mainBundle] zuweisen, werden diese Objekte automatisch freigegeben. Da sie automatisch freigegeben werden, übernimmt iOS automatisch die Speicherverwaltung dieser Objekte für Sie. Deshalb stürzt Ihre App ab, wenn Sie versuchen, sie manuell release.

Initialisieren Sie Ihre NSString s nicht zu neuen Objekten (z. B. [[NSString alloc] init]). Initialisieren sie mit den vereinfachten Methoden sofort:

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

Und nenn nicht release auf einem von ihnen. Auf diese Weise hat Ihre Methode niemals Eigentum an diesen Objekten. Sie werden zufällig nur zur Verwendung weitergegeben.

+0

Ich denke, ich habe es: Ich sollte Variablen nur freigeben, wenn ich ihnen einen Wert wie @ "Foo" zuweisen? – ceyquem

+0

@ceyquem: Sie geben Variablen frei, wenn Sie sie mit Methoden wie 'init',' copy', 'retain' und' new' erhalten. Das 'NSString'-Literal' @ "Foo" 'ist eigentlich ein konstantes Objekt, das nicht automatisch freigegeben wird, aber Sie behandeln es genauso, indem Sie das Release auch nicht manuell aufrufen. – BoltClock