Objective-C Language
Geheugen management
Zoeken…
Automatische referentietelling
Met automatische referentietelling (ARC) retain
de compileerinvoegingen bewaar-, release
en autorelease
verklaringen waar ze nodig zijn, zodat u ze niet zelf hoeft te schrijven. Het schrijft ook dealloc
methoden voor u.
Het voorbeeldprogramma van Manual Memory Management ziet er zo uit met ARC:
@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"];
}
U kunt nog steeds de dealloc-methode overschrijven om bronnen op te ruimen die niet door ARC worden verwerkt. Anders dan bij het gebruik van handmatig geheugenbeheer, roept u niet [super dealloc]
.
-(void)dealloc {
//clean up
}
Sterke en zwakke referenties
Een zwakke referentie lijkt op een van deze:
@property (weak) NSString *property;
NSString *__weak variable;
Als u een zwakke verwijzing naar een object heeft, dan onder de motorkap:
- Je houdt het niet vast.
- Wanneer de toewijzing wordt opgeheven, wordt elke verwijzing ernaar automatisch op
nil
Objectverwijzingen zijn standaard altijd sterk. Maar je kunt expliciet aangeven dat ze sterk zijn:
@property (strong) NSString *property;
NSString *__strong variable;
Een sterke referentie betekent dat terwijl die referentie bestaat, u het object behoudt.
Handmatig geheugenbeheer
Dit is een voorbeeld van een programma geschreven met handmatig geheugenbeheer. Je zou je code echt niet zo moeten schrijven, tenzij je om een of andere reden ARC niet kunt gebruiken (zoals als je 32-bit moet ondersteunen). Het voorbeeld vermijdt @property
notatie om te illustreren hoe u vroeger getters en setters moest schrijven.
@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];
}
Regels voor geheugenbeheer bij handmatige referentietelling.
Deze regels zijn alleen van toepassing als u handmatige referentietelling gebruikt!
U bezit elk object dat u maakt
Door een methode aan te roepen waarvan de naam begint met
alloc
,new
,copy
ofmutableCopy
. Bijvoorbeeld:NSObject *object1 = [[NSObject alloc] init]; NSObject *object2 = [NSObject new]; NSObject *object3 = [object2 copy];
Dat betekent dat u verantwoordelijk bent voor het vrijgeven van deze objecten wanneer u klaar bent.
U kunt eigenaar worden van een object met behulp van behouden
Als u eigenaar wilt worden van een object, roept u de methode behouden aan.
Bijvoorbeeld:
NSObject *object = [NSObject new]; // object already has a retain count of 1 [object retain]; // retain count is now 2
Dit is alleen zinvol in enkele zeldzame situaties.
Wanneer u bijvoorbeeld een accessor of een init-methode implementeert om eigendom te nemen:
- (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; }
Wanneer u het niet langer nodig hebt, moet u afstand doen van het eigendom van een object dat u bezit
NSObject* object = [NSObject new]; // The retain count is now 1 [object performAction1]; // Now we are done with the object [object release]; // Release the object
U mag niet afstand doen van het eigendom van een object dat u niet bezit
Dat betekent dat wanneer u geen eigendom van een object bent geworden, u het niet vrijgeeft.
Autoreleasepool
De autoreleasepool is een codeblok dat elk object in het blok vrijgeeft dat een autorelease-bericht heeft ontvangen.
Voorbeeld:
@autoreleasepool { NSString* string = [NSString stringWithString:@"We don't own this object"]; }
We hebben een string gemaakt zonder eigenaar te worden. De
NSString
methodestringWithString:
moet ervoor zorgen dat de string correct wordt toegewezen nadat deze niet langer nodig is. Voordat de methode retourneert, roept de nieuw gemaakte string de autorelease-methode aan, zodat deze niet de eigenaar hoeft te worden van de string.Dit is hoe de
stringWithString:
wordt geïmplementeerd:+ (NSString *)stringWithString:(NSString *)string { NSString *createdString = [[NSString alloc] initWithString:string]; [createdString autorelease]; return createdString; }
Het is noodzakelijk om autoreleasepool-blokken te gebruiken omdat je soms objecten hebt die niet van jou zijn (de vierde regels zijn niet altijd van toepassing).
Automatische referentietelling zorgt automatisch voor de regels, zodat u dat niet hoeft te doen.