Speicherverwaltung, Mehr zu Objective C
Memory Management
- Objective-C Speicherverwaltung basiert auf expliziter Referenzzählung
[obj retain]Referenzzähler +1[obj release]Referenzzähler -1, bei 0 erfolgt die Freigabe des Objektes[SomeObject alloc]allokiert Speicher für ein Objekt und beinhaltetretain(Objekt wird mit Referenzzähler = 1 zurückgegeben)[obj autorelease]bewirkt ein verzögertesrelease, Objekt bleibt noch eine gewisse Zeit gültig[obj copy]kopiert das Objekt und beinhaltetretain(Objekt wird mit Referenzzähler = 1 zurückgegeben)
Memory Management Regeln
- Jedem
retain-Aufruf (egal ob explizit mitretainoder implizit mitalloc / copy) muss einreleaseoderautorelease-Aufruf gegenüberstehen, sonst entsteht ein Leak. - Convenience-Konstrukturen wie
[NSString stringWithFormat:...]rufen per Konvention internautoreleaseauf - um das zurückgegebene Objekt über die aktuelle Methode hinaus zu behalten, muss es retained werden.
Properties
-
Objective-C-Klassen können Properties definieren, die den Aufruf einer Getter- bzw. Setter-Methode abkürzen:
@interface SomeObject : NSObject { @private NSString* text; } @property NSString* text;
-
Die Definition des Properties ist äquivalent zu der Definition der folgenden Methoden:
- (NSString*) text; - (void) setText: (NSString*) newText;
Properties verwenden
-
Zugriff auf Properties (bzw. entsprechend benannte Methoden) kann per
Dot Syntaxabgekürzt werden, z.B.:someObject.text = @"text"; NSLog(someObject.text);
-
Dies entspricht:
[someObject setText:@"text"]; NSLog([someObject text]);
-
Achtung - Zugriff auf Properties in der Klasse selbst:
// Instanzvariable wird direkt verwendet text = @"text" // Property wird verwendet self.text = @"text";
Properties implementieren
-
Die Implementierung der
getterundsetter-Methoden kann mit@synthesize, eine gleichnamige Instanzvariable vorausgesetzt, durch den Compiler erfolgen:@implementation SomeObject @synthesize text; // ... @end
Properties: Eigenschaften
-
Bei der Definition von Properties können Eigenschaften angegeben werden, die von
@synthesizeberücksichtigt werden (ohne@synthesizemuss die Konformität manuell sichergestellt werden):@property (nonatomic, retain) NSString* text;
-
readwrite(default),readonly -
assign(default),retain(zugewiesene Objekte werden automatisch retained, vorherige Objekte released),copy(bei Zuweisung wird eine Kopie abgelegt) -
atomic(default - Zugriffe von mehreren Threads erfolgen sequentiell),nonatomic(paralleler Zugriff, manuelle Synchronisation notwendig, weniger Overhead) -
getter=someGetterMethod,setter=someSetterMethod: Abweichende Benennung der getter und setter-Methoden
Memory Management: dealloc
-
Um ein Objekt freizugeben, wird vom Laufzeitsystem
[obj dealloc]aufgerufen -
deallocniemals direkt aufrufen (Ausnahme:[super dealloc]indealloc) -
in
dealloc:releasevon allen referenzierten Objekten, dieretainedwurden -
bei
retainodercopy-Properties:self.property = nil;- (void) dealloc { // Freigabe von Instanzvariablen: ownedObj wurde im Initializer mit // [[NSArray alloc] init] erzeugt und muss daher hier released werden [ownedObj release]; // Freigabe von retain oder copy-Properties // Achtung: ohne self würde die Instanzvariable direkt gesetzt und nicht released! self.aProperty = nil; [super dealloc]; }
Cocoa API: NSArray / NSMutableArray I
-
Anlegen mit
nil-terminierter Liste von Argumenten:NSMutableArray* array = [NSMutableArray arrayWithObjects:@"first", @"second", nil]; [array addObject:@"third"];
-
Iteration (
NSArrayimplementiertNSFastEnumeration):for (NSString* str in array) { NSLog(str); }
Cocoa API: NSArray / NSMutableArray II
-
Indexzugriff
for (int i = 0; i < [array count]; i++) { NSLog([array objectAtIndex:i]); }
-
Speicherverwaltung: Container wie
NSArrayverwalten die beinhalteten Objekte;addretaint,removereleast.
Cocoa API: NSDictionary
-
Anlegen mit nil-terminierter Liste paarweiser
value, key(!) Argumente:NSMutableDictionary* dict = [NSMutableDictionary dictionaryWithObjectsAndKeys: @"value1", @"key1", @"value2", @"key2", nil]; [dict setObject:@"value3" forKey:@"key3"];
-
Iteration:
for (id key in dict) { NSLog(@"%@ => %@", key, [dict objectForKey:key]); }
Xcode Debugger
Xcode: gdb-Konsole
-
Debugger-Konsole anzeigen:
Cmd + Shift + R -
C-Daten ausgeben:
p somePointer p (float) [someObject someMessageReturningFloat]
-
Objective C-Objekte ausgeben:
po someInstance po [someInstance someMessageReturningNSObject]
-
Instanz-Variablen beobachten:
watch -location myIvar
Tipps & Tricks: Objective-C Static Analyzer
-
Der
Objective-C Static Analyzerhilft beim Auffinden von Memory Leaks: http://clang.llvm.org/StaticAnalysisUsage.html -
Kann ab Xcode 3.2 direkt aufgerufen werden:
Build > Build and Analyzebzw.Project > Get Info > Build > Build Options > Run Static Analyzer -
Manuelle Verwendung in Xcode 3.1: Herunterladen und entpacken, z.B. nach
/opt/checker-[version]undln -s checker-[version] checker,/opt/checkerin$PATHaufnehmen, im Projektverzeichnis Folgendes ausführen, um das Projekt auf Leaks zu untersuchen:xcodebuild clean scan-build -V xcodebuild -sdk iphonesimulator3.1.3
Tipps & Tricks: Zombie-Objekte
- Fehler ausgelöst durch Aufrufe auf einem bereits freigegebenem Objekt sind schwer zu finden (
FREED(id): message ... sent to freed object=0xabcdef) - Werden Zombie-Objekte aktiviert, werden Objekte nicht mehr freigegeben und ungültige Zugriffe verursachen keinen Crash, sondern eine Log-Meldung, die auch den Typ des jeweiligen Objektes enthält.
- Doppelklick auf
Executable, unterArguments > Variables to be set in the environmentNSZombieEnabledhinzufügen und aufYESsetzen.
Xcode Tipps & Tricks: Build Log anzeigen
-
Build > Build Results (Cmd + Shift + B)
Weitere Informationen
- Memory Management Rules: http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html
- Finding iPhone Memory Leaks: http://www.mobileorchard.com/find-iphone-memory-leaks-a-leaks-tool-tutorial/


Hi Ralf,
Schöne Einführung in die iPhone-Entwicklung! Eine Anmerkung: Sollten (quasi-) "private"-Methoden nicht besser in eine Class continuation rein? (http://stackoverflow.com/questions/172598/best-way-to-define-private-methods-for-a-class-in-objective-c)
Viele Grüße,
Yang