Objective-C iOS Development for Legacy & Enterprise Apps · Pelajaran

Dasar-Dasar Retain-Release Manual (MRR)

Pahami prinsip pengelolaan memori manual, termasuk retain, release, dan kumpulan autorelease.

Pelajaran 1 dari 411 langkah

Dasar-Dasar Retain-Release Manual (MRR) adalah pelajaran Objective-C iOS Development for Legacy & Enterprise Apps gratis di CoddyKit. Ini adalah pelajaran 1 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Objective-C iOS Development for Legacy & Enterprise Apps, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Objective-C iOS Development for Legacy & Enterprise Apps mencakup 4 pelajaran total.

Bagian dari pelajaran ini belum diterjemahkan dan ditampilkan dalam bahasa Inggris.

Welcome to Memory Management

In Objective-C, managing memory is crucial for efficient and stable apps. Before Automatic Reference Counting (ARC) became standard, developers manually handled memory using a system called Manual Retain-Release (MRR).

Understanding MRR helps you work with older codebases and grasp the fundamentals of how ARC works behind the scenes.

What is Reference Counting?

MRR is based on reference counting. Every object has a 'retain count', which is an integer that tracks how many 'owners' an object currently has.

  • When an object is created, its retain count is 1.
  • When an object gains an owner, its retain count increases.
  • When an object loses an owner, its retain count decreases.
  • When the retain count drops to 0, the object is deallocated (destroyed).

Taking Ownership with `retain`

To indicate that you want to keep an object in memory, you send it a retain message. This increases its retain count by one.

Think of it as saying, 'I need this object, don't let it disappear yet!'

Try running this example:

#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;
}

Releasing Ownership with `release`

When you no longer need an object you own, you must send it a release message. This decreases its retain count by one.

If the retain count drops to zero, the object is deallocated, freeing up its memory. Failing to release objects you own leads to memory leaks.

#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;
}

The `dealloc` Method Explained

The dealloc method is a special method that gets called automatically when an object's retain count reaches zero, just before its memory is reclaimed.

You implement dealloc in your custom classes to perform cleanup tasks, such as releasing instance variables that you own, removing observers, or closing file handles.

#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 Ownership Rules

The golden rule for MRR is simple:

  • You own any object you create (using alloc, new, copy, or mutableCopy).
  • You own any object you explicitly retain.
  • You must release any object you own when you are done with it.

If you receive an object from a method that doesn't start with 'alloc', 'new', 'copy', or 'mutableCopy', you generally don't own it and shouldn't release it (unless you explicitly retain it).

Introducing `autorelease`

Sometimes, you need to return an object from a method, but you don't want the caller to have to immediately release it. This is where autorelease comes in.

When you send an object an autorelease message, its retain count is decreased at some point in the future, typically when the current autorelease pool is drained.

It's like saying, 'I'm done with this, but don't deallocate it just yet; let the system handle its eventual release.'

Working with Autorelease Pools

autorelease works with NSAutoreleasePool. Objects marked autorelease are added to the current pool. When the pool is 'drained', all objects in it receive a release message.

In modern Objective-C, you use the @autoreleasepool block syntax. This ensures that temporary objects are released efficiently, preventing memory accumulation.

#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;
}

MRR Best Practices

Writing correct MRR code requires discipline:

  • Balance `retain` and `release` calls: For every retain, alloc, new, copy, or mutableCopy, there must be a corresponding release or autorelease.
  • Don't over-release: Releasing an object more times than it was retained will lead to a crash.
  • Release instance variables in `dealloc`: Make sure to release any objects you retained as instance variables.
  • Call `[super dealloc]` last: In your dealloc method, always call the superclass's dealloc at the very end.

MRR Concepts Check

Consider the following Objective-C code snippet:


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

What is the final state of myString after both release calls, assuming it started with a retain count of 1 from alloc?

Recap: MRR Fundamentals

You've explored the core principles of Manual Retain-Release (MRR):

  • Reference Counting: Objects track ownership with a retain count.
  • `retain`: Increases an object's retain count, indicating ownership.
  • `release`: Decreases an object's retain count; deallocates when count reaches 0.
  • `dealloc`: A special method for cleanup when an object is destroyed.
  • `autorelease`: Defers an object's release until an autorelease pool is drained.

Mastering these basics is key to understanding legacy Objective-C code and the underlying mechanisms of modern memory management!

Gratis untuk memulai

Belajar Objective-C dengan tutor AI — gratis

Tulis dan jalankan kode asli di browser kamu, dapatkan bantuan instan dari tutor AI 24/7, dan lanjutkan di mana kamu tinggalkan di web atau aplikasi.

Kursus
12
Pelajaran
48

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Dasar-Dasar Retain-Release Manual (MRR)” gratis?

Ya — teks lengkap “Dasar-Dasar Retain-Release Manual (MRR)” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Objective-C iOS Development for Legacy & Enterprise Apps, upgrade ke CoddyKit PRO. Kursus Objective-C iOS Development for Legacy & Enterprise Apps mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Dasar-Dasar Retain-Release Manual (MRR)”?

Pahami prinsip pengelolaan memori manual, termasuk retain, release, dan kumpulan autorelease. Kamu berlatih Objective-C iOS Development for Legacy & Enterprise Apps dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Objective-C iOS Development for Legacy & Enterprise Apps?

Tidak diperlukan pengalaman sebelumnya. Objective-C iOS Development for Legacy & Enterprise Apps di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 1 dari 4.

Berapa lama pelajaran “Dasar-Dasar Retain-Release Manual (MRR)” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Objective-C iOS Development for Legacy & Enterprise Apps ini?

Ya. Setiap pelajaran Objective-C iOS Development for Legacy & Enterprise Apps menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Dasar-Dasar Retain-Release Manual (MRR)
  2. Penghitungan Referensi Otomatis (ARC)
  3. Referensi Lemah vs. Kuat
  4. Memutus Siklus Retain dalam Block
← Kembali ke Objective-C iOS Development for Legacy & Enterprise Apps