Objective-C Language
Speicherverwaltung
Suche…
Automatische Referenzzählung
Mit automatischer Referenzzählung (ARC), die Compiler - Einsätze retain
, release
und autorelease
- Anweisungen , wo sie gebraucht wird, so müssen Sie sie selbst nicht schreiben. Es schreibt auch dealloc
Methoden für Sie.
Das Beispielprogramm von Manual Memory Management sieht bei ARC folgendermaßen aus:
@interface MyObject : NSObject {
NSString *_property;
}
@end
@implementation MyObject
@synthesize property = _property;
- (id)initWithProperty:(NSString *)property {
if (self = [super init]) {
_property = property;
}
return self;
}
- (NSString *)property {
return property;
}
- (void)setProperty:(NSString *)property {
_property = property;
}
@end
int main() {
MyObject *obj = [[MyObject alloc] init];
NSString *value = [[NSString alloc] initWithString:@"value"];
[obj setProperty:value];
[obj setProperty:@"value"];
}
Sie können die Dealloc-Methode immer noch überschreiben, um Ressourcen zu bereinigen, die nicht von ARC verarbeitet werden. Anders als bei der manuellen Speicherverwaltung rufen Sie [super dealloc]
.
-(void)dealloc {
//clean up
}
Starke und schwache Referenzen
Eine schwache Referenz sieht so aus:
@property (weak) NSString *property;
NSString *__weak variable;
Wenn Sie einen schwachen Bezug zu einem Objekt haben, dann unter der Haube:
- Du behältst es nicht.
- Wenn es freigegeben wird, wird jeder Verweis darauf automatisch auf
nil
Objektreferenzen sind standardmäßig immer stark. Sie können jedoch ausdrücklich angeben, dass sie stark sind:
@property (strong) NSString *property;
NSString *__strong variable;
Eine starke Referenz bedeutet, dass Sie das Objekt behalten, solange diese Referenz vorhanden ist.
Manuelle Speicherverwaltung
Dies ist ein Beispiel für ein Programm, das mit manueller Speicherverwaltung geschrieben wurde. Sie sollten Ihren Code wirklich nicht so schreiben, es sei denn, Sie können ARC nicht verwenden (z. B. wenn Sie 32-Bit unterstützen müssen). In diesem Beispiel wird die @property
vermieden, @property
zu veranschaulichen, wie Sie früher Getter und Setter schreiben mussten.
@interface MyObject : NSObject {
NSString *_property;
}
@end
@implementation MyObject
@synthesize property = _property;
- (id)initWithProperty:(NSString *)property {
if (self = [super init]) {
// Grab a reference to property to make sure it doesn't go away.
// The reference is released in dealloc.
_property = [property retain];
}
return self;
}
- (NSString *)property {
return [[property retain] autorelease];
}
- (void)setProperty:(NSString *)property {
// Retain, then release. So setting it to the same value won't lose the reference.
[property retain];
[_property release];
_property = property;
}
- (void)dealloc {
[_property release];
[super dealloc]; // Don't forget!
}
@end
int main() {
// create object
// obj is a reference that we need to release
MyObject *obj = [[MyObject alloc] init];
// We have to release value because we created it.
NSString *value = [[NSString alloc] initWithString:@"value"];
[obj setProperty:value];
[value release];
// However, string constants never need to be released.
[obj setProperty:@"value"];
[obj release];
}
Regeln für die Speicherverwaltung bei der manuellen Referenzzählung.
Diese Regeln gelten nur, wenn Sie die manuelle Referenzzählung verwenden!
Sie besitzen jedes Objekt, das Sie erstellen
Durch Aufruf einer Methode, deren Name mit
alloc
,new
,copy
odermutableCopy
. Zum Beispiel:NSObject *object1 = [[NSObject alloc] init]; NSObject *object2 = [NSObject new]; NSObject *object3 = [object2 copy];
Das bedeutet, dass Sie für die Freigabe dieser Objekte verantwortlich sind, wenn Sie mit ihnen fertig sind.
Sie können den Besitz eines Objekts über einbehalten
Um den Besitz eines Objekts zu übernehmen, rufen Sie die Retain-Methode auf.
Zum Beispiel:
NSObject *object = [NSObject new]; // object already has a retain count of 1 [object retain]; // retain count is now 2
Das macht nur in seltenen Situationen Sinn.
Wenn Sie beispielsweise einen Accessor oder eine Init-Methode implementieren, um den Besitz zu übernehmen:
- (void)setStringValue:(NSString *)stringValue { [_privateStringValue release]; // Release the old value, you no longer need it [stringValue retain]; // You make sure that this object does not get deallocated outside of your scope. _privateStringValue = stringValue; }
Wenn Sie es nicht mehr benötigen, müssen Sie das Eigentum an einem Objekt, das Sie besitzen, abgeben
NSObject* object = [NSObject new]; // The retain count is now 1 [object performAction1]; // Now we are done with the object [object release]; // Release the object
Sie dürfen das Eigentum an einem Objekt, das Sie nicht besitzen, nicht aufgeben
Das heißt, wenn Sie kein Eigentum in Besitz genommen haben, geben Sie es nicht frei.
Autoreleasepool
Der Autoreleasepool ist ein Codeblock, der jedes Objekt in dem Block freigibt, das eine Autorelease-Nachricht erhalten hat.
Beispiel:
@autoreleasepool { NSString* string = [NSString stringWithString:@"We don't own this object"]; }
Wir haben eine Zeichenfolge erstellt, ohne den Besitzer zu übernehmen. Die
NSString
MethodestringWithString:
muss sicherstellen, dass die Zeichenfolge ordnungsgemäß freigegeben wird, nachdem sie nicht mehr benötigt wird. Bevor die Methode den neu erstellten String zurückgibt, ruft er die Autorelease-Methode auf, sodass er nicht den Besitz des Strings übernehmen muss.So wird der
stringWithString:
implementiert:+ (NSString *)stringWithString:(NSString *)string { NSString *createdString = [[NSString alloc] initWithString:string]; [createdString autorelease]; return createdString; }
Es ist notwendig, Autoreleasepool-Blöcke zu verwenden, da manchmal Objekte vorhanden sind, die Sie nicht besitzen (die vierte Regel gilt nicht immer).
Die automatische Referenzzählung berücksichtigt automatisch die Regeln, so dass Sie dies nicht tun müssen.