ARC hanya memainkan old retain / release (MRC) dengan kompiler mencari tahu kapan harus memanggil retain / release. Ini akan cenderung memiliki kinerja yang lebih tinggi, penggunaan memori puncak yang lebih rendah, dan kinerja yang lebih dapat diprediksi daripada sistem GC.
Di sisi lain beberapa jenis struktur data tidak dimungkinkan dengan ARC (atau MRC), sementara GC dapat menanganinya.
Sebagai contoh, jika Anda memiliki kelas bernama simpul, dan simpul memiliki NSArray anak-anak, dan satu referensi ke induknya yang "hanya bekerja" dengan GC. Dengan ARC (dan penghitungan referensi manual juga) Anda memiliki masalah. Setiap simpul yang diberikan akan dirujuk dari anak-anaknya dan juga dari orang tuanya.
Suka:
A -> [B1, B2, B3]
B1 -> A, B2 -> A, B3 -> A
Semua baik-baik saja saat Anda menggunakan A (katakanlah melalui variabel lokal).
Ketika Anda selesai dengan itu (dan B1 / B2 / B3), sistem GC pada akhirnya akan memutuskan untuk melihat segala sesuatu yang dapat ditemukan mulai dari stack dan register CPU. Ia tidak akan pernah menemukan A, B1, B2, B3 sehingga akan menyelesaikannya dan mendaur ulang memori ke objek lain.
Ketika Anda menggunakan ARC atau MRC, dan selesai dengan A itu memiliki refcount dari 3 (B1, B2, dan B3 semua referensi itu), dan B1 / B2 / B3 semua akan memiliki jumlah referensi 1 (A's NSArray memegang satu referensi ke setiap). Jadi semua benda itu tetap hidup meskipun tidak ada yang bisa menggunakannya.
Solusi umum adalah memutuskan salah satu dari referensi tersebut harus lemah (tidak berkontribusi pada jumlah referensi). Itu akan berfungsi untuk beberapa pola penggunaan, misalnya jika Anda mereferensikan B1 / B2 / B3 hanya melalui A. Namun dalam pola lain itu gagal. Misalnya jika Anda kadang-kadang akan memegang B1, dan berharap untuk naik kembali melalui pointer orangtua dan menemukan A. Dengan referensi yang lemah jika Anda hanya memegang B1, kaleng (dan biasanya akan) menguap, dan mengambil B2, dan B3 dengan itu.
Terkadang ini bukan masalah, tetapi beberapa cara yang sangat berguna dan alami untuk bekerja dengan struktur data yang kompleks sangat sulit digunakan dengan ARC / MRC.
Jadi ARC menargetkan jenis masalah yang sama dengan target GC. Namun ARC bekerja pada pola penggunaan yang lebih terbatas daripada GC, jadi jika Anda menggunakan bahasa GC (seperti Java) dan mencangkokkan sesuatu seperti ARC ke dalamnya, beberapa program tidak akan berfungsi lagi (atau setidaknya akan menghasilkan banyak memori yang ditinggalkan) , dan dapat menyebabkan masalah pertukaran serius atau kehabisan memori atau ruang swap).
Anda juga dapat mengatakan ARC menempatkan prioritas yang lebih besar pada kinerja (atau mungkin dapat diprediksi) sementara GC menempatkan prioritas yang lebih besar untuk menjadi solusi generik. Akibatnya, GC memiliki tuntutan CPU / memori yang kurang dapat diprediksi, dan kinerja yang lebih rendah (biasanya) dari ARC, tetapi dapat menangani pola penggunaan apa pun. ARC akan bekerja lebih baik untuk banyak pola penggunaan umum, tetapi untuk beberapa pola penggunaan (valid!) Akan jatuh dan mati.