Manajemen Memori Obj-C
Manajemen memori adalah salah satu proses terpenting dalam bahasa pemrograman apa pun. Ini adalah proses di mana memori objek dialokasikan saat dibutuhkan dan dialokasikan saat tidak lagi diperlukan.
Mengelola memori objek adalah masalah kinerja; jika aplikasi tidak membebaskan objek yang tidak dibutuhkan, jejak memorinya akan bertambah dan kinerjanya akan menurun.
Teknik manajemen memori Objective-C secara luas dapat diklasifikasikan menjadi dua jenis.
- "Manual Retain-Release" atau MRR
- "Penghitungan Referensi Otomatis" atau ARC
"Manual Retain-Release" atau MRR
Di MRR, kami secara eksplisit mengelola memori dengan melacak objek sendiri. Ini diimplementasikan menggunakan model, yang dikenal sebagai penghitungan referensi, yang disediakan NSObject kelas Foundation dalam hubungannya dengan lingkungan runtime.
Satu-satunya perbedaan antara MRR dan ARC adalah bahwa penyimpanan dan pelepasan ditangani oleh kami secara manual di versi sebelumnya sementara yang terakhir secara otomatis ditangani oleh kami.
Gambar berikut mewakili contoh cara kerja manajemen memori di Objective-C.
Siklus hidup memori dari objek Kelas A ditunjukkan pada gambar di atas. Seperti yang Anda lihat, jumlah retensi ditampilkan di bawah objek, ketika jumlah retensi suatu objek menjadi 0, objek dibebaskan sepenuhnya dan memorinya dibatalkan alokasinya untuk digunakan objek lain.
Objek kelas A pertama kali dibuat menggunakan metode alokasi / init yang tersedia di NSObject. Sekarang, jumlah retensi menjadi 1.
Sekarang, kelas B mempertahankan Objek Kelas A dan jumlah penahan objek Kelas A menjadi 2.
Kemudian, Kelas C membuat salinan objek tersebut. Sekarang, itu dibuat sebagai instance lain dari Kelas A dengan nilai yang sama untuk variabel instance. Di sini, jumlah retensi adalah 1 dan bukan hitungan retensi dari benda aslinya. Ini diwakili oleh garis putus-putus pada gambar.
Objek yang disalin dilepaskan oleh Kelas C menggunakan metode rilis dan jumlah retensi menjadi 0 dan karenanya objek dimusnahkan.
Dalam kasus Objek Kelas A awal, jumlah retensi adalah 2 dan harus dilepaskan dua kali agar bisa dimusnahkan. Hal ini dilakukan dengan pernyataan rilis Kelas A dan Kelas B yang masing-masing mengurangi jumlah retensi menjadi 1 dan 0. Akhirnya, objek tersebut dihancurkan.
Aturan Dasar MRR
Kami memiliki objek apa pun yang kami buat: Kami membuat objek menggunakan metode yang namanya dimulai dengan "alokasi", "baru", "salin", atau "mutableCopy"
Kita dapat mengambil kepemilikan suatu objek menggunakan retensi: Objek yang diterima biasanya dijamin tetap valid dalam metode penerimaannya, dan metode itu juga dapat mengembalikan objek ke invokernya dengan aman. Kami menggunakan retensi dalam dua situasi -
Dalam implementasi metode pengakses atau metode init, untuk mengambil kepemilikan objek yang ingin kita simpan sebagai nilai properti.
Untuk mencegah objek menjadi tidak valid sebagai efek samping dari beberapa operasi lainnya.
Saat kita tidak lagi membutuhkannya, kita harus melepaskan kepemilikan atas objek yang kita miliki: Kita melepaskan kepemilikan objek dengan mengirimkannya pesan rilis atau pesan autorelease. Dalam terminologi Cocoa, melepaskan kepemilikan suatu objek oleh karena itu biasanya disebut sebagai "melepaskan" suatu objek.
Anda tidak boleh melepaskan kepemilikan atas objek yang bukan milik Anda: Ini hanya akibat wajar dari aturan kebijakan sebelumnya yang dinyatakan secara eksplisit.
#import <Foundation/Foundation.h>
@interface SampleClass:NSObject
- (void)sampleMethod;
@end
@implementation SampleClass
- (void)sampleMethod {
NSLog(@"Hello, World! \n");
}
- (void)dealloc {
NSLog(@"Object deallocated");
[super dealloc];
}
@end
int main() {
/* my first program in Objective-C */
SampleClass *sampleClass = [[SampleClass alloc]init];
[sampleClass sampleMethod];
NSLog(@"Retain Count after initial allocation: %d",
[sampleClass retainCount]);
[sampleClass retain];
NSLog(@"Retain Count after retain: %d", [sampleClass retainCount]);
[sampleClass release];
NSLog(@"Retain Count after release: %d", [sampleClass retainCount]);
[sampleClass release];
NSLog(@"SampleClass dealloc will be called before this");
// Should set the object to nil
sampleClass = nil;
return 0;
}
Saat kita mengkompilasi program di atas, kita akan mendapatkan keluaran sebagai berikut.
2013-09-28 04:39:52.310 demo[8385] Hello, World!
2013-09-28 04:39:52.311 demo[8385] Retain Count after initial allocation: 1
2013-09-28 04:39:52.311 demo[8385] Retain Count after retain: 2
2013-09-28 04:39:52.311 demo[8385] Retain Count after release: 1
2013-09-28 04:39:52.311 demo[8385] Object deallocated
2013-09-28 04:39:52.311 demo[8385] SampleClass dealloc will be called before this
"Penghitungan Referensi Otomatis" atau ARC
Dalam Penghitungan Referensi Otomatis atau ARC, sistem menggunakan sistem penghitungan referensi yang sama seperti MRR, tetapi menyisipkan panggilan metode manajemen memori yang sesuai untuk kita pada waktu kompilasi. Kami sangat dianjurkan untuk menggunakan ARC untuk proyek baru. Jika kami menggunakan ARC, biasanya tidak perlu memahami implementasi yang mendasari yang dijelaskan dalam dokumen ini, meskipun mungkin dalam beberapa situasi dapat membantu. Untuk selengkapnya tentang ARC, lihat Transisi ke Catatan Rilis ARC.
Seperti disebutkan di atas, di ARC, kita tidak perlu menambahkan metode rilis dan penyimpanan karena itu akan ditangani oleh kompilator. Sebenarnya, proses yang mendasari Objective-C masih sama. Ini menggunakan operasi pertahankan dan lepaskan secara internal sehingga memudahkan pengembang untuk membuat kode tanpa mengkhawatirkan operasi ini, yang akan mengurangi jumlah kode yang ditulis dan kemungkinan kebocoran memori.
Ada prinsip lain yang disebut pengumpulan sampah, yang digunakan di Mac OS-X bersama dengan MRR, tetapi karena tidak digunakan lagi di OS-X Mountain Lion, hal itu belum dibahas bersama MRR. Selain itu, objek iOS tidak pernah memiliki fitur pengumpulan sampah. Dan dengan ARC, tidak ada penggunaan pengumpulan sampah di OS-X juga.
Berikut adalah contoh ARC sederhana. Perhatikan bahwa ini tidak akan berfungsi pada kompiler online karena tidak mendukung ARC.
#import <Foundation/Foundation.h>
@interface SampleClass:NSObject
- (void)sampleMethod;
@end
@implementation SampleClass
- (void)sampleMethod {
NSLog(@"Hello, World! \n");
}
- (void)dealloc {
NSLog(@"Object deallocated");
}
@end
int main() {
/* my first program in Objective-C */
@autoreleasepool {
SampleClass *sampleClass = [[SampleClass alloc]init];
[sampleClass sampleMethod];
sampleClass = nil;
}
return 0;
}
Saat kita mengkompilasi program di atas, kita akan mendapatkan keluaran sebagai berikut.
2013-09-28 04:45:47.310 demo[8385] Hello, World!
2013-09-28 04:45:47.311 demo[8385] Object deallocated