Objective-C-iOS-ontwikkeling voor legacy- en bedrijfsapps · Les

De basis van handmatig retain-releasebeheer (MRR)

Begrijp de principes van handmatig geheugenbeheer, waaronder retain, release en autorelease-pools.

Les 1 van 411 stappen

De basis van handmatig retain-releasebeheer (MRR) is een gratis Objective-C-iOS-ontwikkeling voor legacy- en bedrijfsapps-les op CoddyKit. Dit is les 1 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Objective-C-iOS-ontwikkeling voor legacy- en bedrijfsapps. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Objective-C-iOS-ontwikkeling voor legacy- en bedrijfsapps bevat in totaal 4 lessen.

Welkom bij geheugenbeheer

In Objective-C is geheugenbeheer cruciaal voor efficiënte en stabiele apps. Voordat Automatic Reference Counting (ARC) de standaard werd, beheerden ontwikkelaars het geheugen handmatig met een systeem dat Manual Retain-Release (MRR) heet.

Als je MRR begrijpt, kun je met oudere codebases werken en krijg je inzicht in de basisprincipes van de werking van ARC achter de schermen.

Wat is referentietelling?

MRR is gebaseerd op referentietelling. Elk object heeft een 'retain count', een geheel getal dat bijhoudt hoeveel 'eigenaars' een object momenteel heeft.

  • Wanneer een object wordt gemaakt, is de retain count 1.
  • Wanneer een object een eigenaar krijgt, neemt de retain count toe.
  • Wanneer een object een eigenaar verliest, neemt de retain count af.
  • Wanneer de retain count 0 bereikt, wordt het object vrijgegeven (vernietigd).

Eigenaarschap nemen met `retain`

Als je wilt aangeven dat je een object in het geheugen wilt houden, stuur je het een bericht retain. Hierdoor neemt de retain count met één toe.

Zie het als de uitspraak: 'Ik heb dit object nodig, laat het nog niet verdwijnen!'

Probeer dit voorbeeld uit te voeren:

#import <Foundation/Foundation.h>

@interface MyObject : NSObject
@end

@implementation MyObject
- (id)init {
    self = [super init];
    if (self) {
        NSLog(@"MyObject created. Retain count: %lu", [self retainCount]);
    }
    return self;
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        MyObject *obj = [[MyObject alloc] init]; // Retain count is 1
        [obj retain]; // Retain count becomes 2
        NSLog(@"After retain: %lu", [obj retainCount]);

        // Note: We'll learn about 'release' soon!
    }
    return 0;
}

Eigenaarschap vrijgeven met `release`

Wanneer je een object waarvan je eigenaar bent niet meer nodig hebt, moet je het een bericht release sturen. Hierdoor neemt de retain count met één af.

Als de retain count tot nul daalt, wordt het object vrijgegeven en komt het geheugen vrij. Als je objecten waarvan je eigenaar bent niet vrijgeeft, ontstaan er geheugenlekken.

#import <Foundation/Foundation.h>

@interface MyObject : NSObject
@end

@implementation MyObject
- (id)init {
    self = [super init];
    if (self) {
        NSLog(@"MyObject created. Retain count: %lu", [self retainCount]);
    }
    return self;
}
- (void)dealloc {
    NSLog(@"MyObject deallocated.");
    [super dealloc]; // Always call super's dealloc
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        MyObject *obj = [[MyObject alloc] init]; // Retain count 1
        [obj retain]; // Retain count 2
        NSLog(@"After retain: %lu", [obj retainCount]);

        [obj release]; // Retain count 1
        NSLog(@"After first release: %lu", [obj retainCount]);
        [obj release]; // Retain count 0, object deallocated
    }
    return 0;
}

De methode `dealloc` uitgelegd

De methode dealloc is een speciale methode die automatisch wordt aangeroepen wanneer de retain count van een object nul bereikt, vlak voordat het geheugen ervan wordt teruggewonnen.

Je implementeert dealloc in je aangepaste klassen om opruimtaken uit te voeren, zoals het vrijgeven van instantievariabelen waarvan je eigenaar bent, het verwijderen van observers of het sluiten van bestandsdescriptors.

#import <Foundation/Foundation.h>

@interface MyClass : NSObject {
    NSString *_name;
}
- (id)initWithName:(NSString *)name;
@end

@implementation MyClass
- (id)initWithName:(NSString *)name {
    self = [super init];
    if (self) {
        _name = [name retain]; // Retain the name string
        NSLog(@"MyClass '%@' initialized. Retain count: %lu", _name, [self retainCount]);
    }
    return self;
}

- (void)dealloc {
    NSLog(@"MyClass '%@' is being deallocated.", _name);
    [_name release]; // Release instance variables you own
    _name = nil;     // Set to nil to prevent dangling pointers
    [super dealloc]; // Always call super's dealloc LAST
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        MyClass *myObject = [[MyClass alloc] initWithName:@"Coddy"];
        // Do something with myObject
        [myObject release]; // Release the object when done
    }
    return 0;
}

MRR-regels voor eigenaarschap

De gouden regel voor MRR is eenvoudig:

  • Je bent eigenaar van elk object dat je maakt (met alloc, new, copy of mutableCopy).
  • Je bent eigenaar van elk object dat je expliciet retain uitvoert.
  • Je moet elk object waarvan je eigenaar bent release zodra je ermee klaar bent.

Als je een object ontvangt van een methode die niet begint met 'alloc', 'new', 'copy' of 'mutableCopy', ben je er over het algemeen geen eigenaar van en moet je het niet vrijgeven (tenzij je het expliciet met retain hebt behouden).

`autorelease` introduceren

Soms moet je een object vanuit een methode retourneren, maar wil je niet dat de aanroeper het onmiddellijk moet vrijgeven. Daarvoor gebruik je autorelease.

Wanneer je een object een bericht autorelease stuurt, wordt de retain count op een later moment verlaagd, meestal wanneer de huidige autoreleasepool wordt geleegd.

Het is alsof je zegt: 'Ik ben hiermee klaar, maar geef het nog niet vrij; laat het systeem de uiteindelijke vrijgave afhandelen.'

Werken met autoreleasepools

autorelease werkt samen met NSAutoreleasePool. Objecten die met autorelease zijn gemarkeerd, worden aan de huidige pool toegevoegd. Wanneer de pool wordt 'geleegd', ontvangen alle objecten erin een bericht release.

In modern Objective-C gebruik je de bloksyntaxis @autoreleasepool. Dit zorgt ervoor dat tijdelijke objecten efficiënt worden vrijgegeven en voorkomt dat geheugen zich ophoopt.

#import <Foundation/Foundation.h>

@interface MyObject : NSObject
@end

@implementation MyObject
- (id)init {
    self = [super init];
    if (self) {
        NSLog(@"MyObject created.");
    }
    return self;
}
- (void)dealloc {
    NSLog(@"MyObject deallocated.");
    [super dealloc];
}
@end

MyObject *createAndAutoreleaseObject() {
    MyObject *obj = [[MyObject alloc] init];
    NSLog(@"Object retain count before autorelease: %lu", [obj retainCount]);
    return [obj autorelease]; // Defer release until pool drains
}

int main(int argc, const char * argv[]) {
    NSLog(@"Before autoreleasepool block");
    @autoreleasepool {
        NSLog(@"Inside autoreleasepool block");
        MyObject *a = createAndAutoreleaseObject();
        // 'a' is valid here
        NSLog(@"Object retain count after autorelease: %lu", [a retainCount]);
    }
    NSLog(@"After autoreleasepool block. Object should be deallocated.");
    return 0;
}

Aanbevolen werkwijzen voor MRR

Correcte MRR-code schrijven vereist discipline:

  • Breng aanroepen van `retain` en `release` met elkaar in evenwicht: Voor elke retain, alloc, new, copy of mutableCopy moet er een bijbehorende release of autorelease zijn.
  • Geef niet te vaak vrij: Als je een object vaker vrijgeeft dan het is behouden, leidt dat tot een crash.
  • Geef instantievariabelen vrij in `dealloc`: Zorg dat je alle objecten vrijgeeft die je als instantievariabelen hebt behouden.
  • Roep `[super dealloc]` als laatste aan: Roep in je dealloc-methode de dealloc van de superklasse altijd helemaal aan het einde aan.

Controle van MRR-concepten

Bekijk het volgende Objective-C-codefragment:


NSString *myString = [[NSString alloc] initWithFormat:@"Hello"];
[myString retain];
// ... some operations ...
[myString release];
// ... more operations ...
[myString release];

Wat is de uiteindelijke toestand van myString na beide aanroepen van release, ervan uitgaande dat het object door alloc begon met een retain-telling van 1?

Samenvatting: de basis van MRR

Je hebt de kernprincipes van Manual Retain-Release (MRR) verkend:

  • Referentietelling: Objecten houden het eigendom bij met een retain-telling.
  • `retain`: Verhoogt de retain-telling van een object en geeft aan dat je eigenaar bent.
  • `release`: Verlaagt de retain-telling van een object; het object wordt gedealloceerd wanneer de telling 0 bereikt.
  • `dealloc`: Een speciale methode voor opruimwerk wanneer een object wordt vernietigd.
  • `autorelease`: Stelt het vrijgeven van een object uit totdat een autorelease-pool wordt geleegd.

Deze basis beheersen is belangrijk om verouderde Objective-C-code en de onderliggende mechanismen van modern geheugenbeheer te begrijpen!

Gratis beginnen

Leer Objective-C met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
12
Lessen
48

Veelgestelde vragen

Is de les “De basis van handmatig retain-releasebeheer (MRR)” gratis?

Ja — de volledige tekst van “De basis van handmatig retain-releasebeheer (MRR)” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Objective-C-iOS-ontwikkeling voor legacy- en bedrijfsapps wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Objective-C-iOS-ontwikkeling voor legacy- en bedrijfsapps bevat in totaal 4 lessen.

Wat leer ik in “De basis van handmatig retain-releasebeheer (MRR)”?

Begrijp de principes van handmatig geheugenbeheer, waaronder retain, release en autorelease-pools. Je oefent met Objective-C-iOS-ontwikkeling voor legacy- en bedrijfsapps door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Objective-C-iOS-ontwikkeling voor legacy- en bedrijfsapps te beginnen?

Ervaring vooraf is niet nodig. Objective-C-iOS-ontwikkeling voor legacy- en bedrijfsapps op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 1 van 4.

Hoe lang duurt de les “De basis van handmatig retain-releasebeheer (MRR)”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Objective-C-iOS-ontwikkeling voor legacy- en bedrijfsapps?

Ja. Elke les over Objective-C-iOS-ontwikkeling voor legacy- en bedrijfsapps bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. De basis van handmatig retain-releasebeheer (MRR)
  2. Automatic Reference Counting (ARC)
  3. Zwakke versus sterke referenties
  4. Retain-cycli in blocks doorbreken
← Terug naar Objective-C-iOS-ontwikkeling voor legacy- en bedrijfsapps