it-swarm-id.com

Bagaimana cara kerja kumpulan autorelease NSAutoreleasePool?

Seperti yang saya pahami, apa pun yang dibuat dengan-okasikan , baru , atau salin perlu dirilis secara manual. Sebagai contoh:

int main(void) {
    NSString *string;
    string = [[NSString alloc] init];
    /* use the string */
    [string release];
}

Pertanyaan saya, bukankah ini sama validnya ?:

int main(void) {
    NSAutoreleasePool *pool;
    pool = [[NSAutoreleasePool alloc] init];
    NSString *string;
    string = [[[NSString alloc] init] autorelease];
    /* use the string */
    [pool drain];
}
94
James Sumners

Ya, cuplikan kode kedua Anda benar-benar valid.

Setiap kali autorelease dikirimkan ke objek, ia ditambahkan ke kumpulan autorelease paling dalam. Ketika kolam dikeringkan, itu hanya mengirim -hentikan ke semua objek di kolam.

Autorelease pools hanyalah sebuah kenyamanan yang memungkinkan Anda untuk menunda pengiriman -tanggal hingga "nanti". "Nanti" itu dapat terjadi di beberapa tempat, tetapi yang paling umum dalam aplikasi GUI Kakao adalah pada akhir siklus putaran saat ini.

65
kperryua

NSAutoreleasePool: tiriskan vs rilis

Karena fungsi drain dan release tampaknya menyebabkan kebingungan, mungkin perlu diperjelas di sini (walaupun hal ini dibahas dalam dokumentasi ...).

Sebenarnya, dari perspektif gambaran besar drain adalah tidak setara dengan release:

Dalam lingkungan yang dihitung referensi, drain melakukan operasi yang sama dengan release, sehingga keduanya dalam arti yang setara. Untuk menekankan, ini berarti Anda melakukan tidak membocorkan kumpulan jika Anda menggunakan drain daripada release.

Dalam lingkungan yang dikumpulkan sampah, release adalah no-op. Jadi itu tidak berpengaruh. drain, di sisi lain, berisi petunjuk kepada kolektor bahwa ia harus "mengumpulkan jika diperlukan". Jadi dalam lingkungan pengumpulan sampah, menggunakan drain membantu keseimbangan pengumpulan sistem menyapu.

37
mmalc

Seperti yang telah ditunjukkan, cuplikan kode kedua Anda sudah benar.

Saya ingin menyarankan cara yang lebih ringkas dalam menggunakan kumpulan autorelease yang bekerja pada semua lingkungan (penghitungan ref, GC, ARC) dan juga menghindari kebingungan drain/release:

int main(void) {
  @autoreleasepool {
    NSString *string;
    string = [[[NSString alloc] init] autorelease];
    /* use the string */
  }
}

Pada contoh di atas, harap perhatikan blok @autoreleasepool. Ini didokumentasikan di sini .

17
Neovibrant

Tidak, kamu salah. Dokumentasi menyatakan dengan jelas bahwa di bawah non-GC, -drain setara dengan -release, artinya NSAutoreleasePool akan tidak bocor.

7
kperryua

Saya menemukan tautan ini memberikan penjelasan terbaik tentang kapan dan bagaimana menggunakan NSAutoReleasePool: AutoReleasePool

1
Wayne Lo

mengirim autorelease alih-alih melepaskan ke objek memperpanjang usia objek itu setidaknya sampai kolam itu sendiri dikeringkan (mungkin lebih lama jika objek kemudian dipertahankan). Suatu objek dapat dimasukkan ke dalam kumpulan yang sama beberapa kali, dalam hal ini ia menerima pesan rilis untuk setiap kali ia dimasukkan ke dalam kumpulan.

0
Hardik Mamtora

ya kode Anda sempurna, jika Anda akan menggunakan pengumpulan sampah itu akan cukup dengan hanya mengatur string ke nol ketika Anda selesai dengan itu. Pengumpulan sampah tidak baik untuk kinerja aplikasi Anda, jadi saya tidak akan merekomendasikan menggunakannya: P

0
Antwan van Houdt

Apa yang saya baca dari Apple: "Di akhir blok kumpulan autorelease, objek yang menerima pesan autorelease di dalam blok dikirimi pesan pelepasan — sebuah objek menerima pesan rilis untuk setiap kali dikirim pesan autorelease di dalam blok. "

https://developer.Apple.com/library/mac/documentation/cocoa/conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html

0
Gagan_iOS