Bagaimana saya bisa menghindari peringatan ini di xcode. Berikut ini cuplikan kode:
[player(AVPlayer object) addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(0.1, 100)
queue:nil usingBlock:^(CMTime time) {
current+=1;
if(current==60)
{
min+=(current/60);
current = 0;
}
[timerDisp(UILabel) setText:[NSString stringWithFormat:@"%02d:%02d",min,current]];///warning occurs in this line
}];
objective-c
cocoa-touch
automatic-ref-counting
avplayer
retain
pengguna1845209
sumber
sumber
timerDisp
ada properti di kelas?player(AVPlayer object)
dantimerDisp(UILabel)
?Jawaban:
Pengambilan dari
self
sini datang dengan akses properti implisitself.timerDisp
Anda - Anda tidak dapat merujukself
atau propertiself
dari dalam blok yang akan sangat dipertahankan olehself
.Anda dapat menyiasatinya dengan membuat referensi yang lemah
self
sebelum mengaksestimerDisp
di dalam blok Anda:sumber
__unsafe_unretained
sebagai gantinya.self
, itu dipertahankan oleh antrian pengiriman utama. Apakah aku salah?Dan satu hal yang sangat penting untuk diingat: jangan gunakan variabel instan langsung di blok, gunakan itu sebagai properti dari objek yang lemah, contoh:
dan jangan lupa lakukan:
masalah lain dapat muncul jika Anda akan melewati salinan lemah yang tidak disimpan oleh objek siapa pun:
jika
vcToGo
akan dibatalkan alokasi dan kemudian blok ini dipecat Saya yakin Anda akan mendapatkan crash dengan pemilih yang tidak dikenal ke tempat sampah yang berisivcToGo_
variabel sekarang. Cobalah untuk mengendalikannya.sumber
Versi yang lebih baik
Jadi semuanya akan seperti ini:
Saya telah membaca artikel ini berkali-kali. Ini adalah artikel yang sangat bagus oleh Erica Sadun tentang Cara Menghindari Masalah Saat Menggunakan Blok Dan NSNotificationCenter
Pembaruan cepat:
Misalnya, dengan cepat metode sederhana dengan blok sukses adalah:
Ketika kita memanggil metode ini dan perlu digunakan
self
di blok sukses. Kami akan menggunakan fitur[weak self]
danguard let
.Tarian kuat-lemah ini digunakan oleh proyek open source populer
Alamofire
.Untuk info lebih lanjut, lihat panduan gaya cepat
sumber
typeof(self) strongSelf = self;
luar blok (bukan __weak) kemudian di blok tersebut dikatakanstrongSelf = nil;
setelah digunakan? Saya tidak melihat bagaimana contoh Anda memastikan bahwa kelemahan tidak nol pada saat blok dijalankan.Dalam jawaban lain, Tim berkata:
Ini tidak sepenuhnya benar. Tidak apa-apa bagi Anda untuk melakukan ini selama Anda memutus siklus di beberapa titik. Sebagai contoh, katakanlah Anda memiliki timer yang menyala yang memiliki blok yang mempertahankan diri dan Anda juga menyimpan referensi yang kuat untuk timer itu sendiri. Ini sangat baik jika Anda selalu tahu bahwa Anda akan menghancurkan timer di beberapa titik dan memutus siklus.
Dalam kasus saya barusan, saya mendapat peringatan untuk kode ini:
Sekarang saya tahu bahwa dentang hanya akan menghasilkan peringatan ini jika mendeteksi metode dimulai dengan "set" (dan satu kasus khusus lainnya yang tidak akan saya sebutkan di sini). Bagi saya, saya tahu tidak ada bahaya jika ada retain loop, jadi saya mengubah nama metode menjadi "useY:" Tentu saja, itu mungkin tidak sesuai dalam semua kasus dan biasanya Anda ingin menggunakan referensi yang lemah, tetapi Saya pikir perlu dicatat solusi saya jika itu membantu orang lain.
sumber
Banyak kali, ini sebenarnya bukan siklus mempertahankan .
Jika Anda tahu itu bukan, Anda tidak perlu membawa Diri yang lemah yang sia-sia ke dunia.
Apple bahkan memaksa peringatan ini kepada kami dengan API ke mereka
UIPageViewController
, yang mencakup metode set (yang memicu peringatan ini - seperti yang disebutkan di tempat lain - berpikir Anda menetapkan nilai ke sebuah ivar yang merupakan blok) dan blok handler penyelesaian (di mana Anda pasti akan merujuk pada diri Anda sendiri).Berikut ini beberapa arahan kompiler untuk menghapus peringatan dari satu baris kode:
sumber
Menambahkan dua sen untuk meningkatkan ketepatan dan gaya. Dalam kebanyakan kasus, Anda hanya akan menggunakan satu atau beberapa anggota
self
di blok ini, kemungkinan besar hanya untuk memperbarui slider. Castingself
itu berlebihan. Alih-alih, lebih baik untuk eksplisit dan melemparkan hanya objek yang benar-benar Anda butuhkan di dalam blok. Misalnya, jika ini merupakan contoh dariUISlider*
, katakanlah,_timeSlider
lakukan saja hal berikut sebelum deklarasi blok:Kemudian gunakan saja
slider
di dalam blok. Secara teknis ini lebih tepat karena mempersempit siklus mempertahankan potensial hanya untuk objek yang Anda butuhkan, tidak semua objek di dalamself
.Contoh lengkap:
Selain itu, kemungkinan besar objek yang dilemparkan ke pointer lemah sudah menjadi pointer lemah di dalam
self
juga meminimalkan atau menghilangkan sepenuhnya kemungkinan siklus penahan. Dalam contoh di atas,_timeSlider
sebenarnya properti disimpan sebagai referensi yang lemah, misalnya:Dalam hal gaya pengkodean, seperti halnya dengan C dan C ++, deklarasi variabel lebih baik dibaca dari kanan ke kiri. Menyatakan
SomeType* __weak variable
dalam rangka ini berbunyi lebih alami dari kanan ke kiri sebagai:variable is a weak pointer to SomeType
.sumber
Saya mengalami peringatan ini baru-baru ini dan ingin memahaminya sedikit lebih baik. Setelah sedikit trial and error, saya menemukan bahwa itu berasal dari memiliki metode mulai dengan "tambah" atau "simpan". Objective C memperlakukan nama metode yang dimulai dengan "baru", "mengalokasikan", dll sebagai mengembalikan objek yang dipertahankan tetapi tidak menyebutkan (bahwa saya dapat menemukan) apa pun tentang "tambah" atau "simpan". Namun, jika saya menggunakan nama metode dengan cara ini:
Saya akan melihat peringatan di baris [dilakukan sendiri]. Namun, ini tidak akan:
Saya akan pergi ke depan dan menggunakan cara "__weak __typeof (diri) lemahSelf = diri" untuk referensi objek saya tetapi benar-benar tidak suka harus melakukannya karena akan membingungkan masa depan saya dan / atau dev lainnya. Tentu saja, saya juga tidak bisa menggunakan "add" (atau "save") tapi itu lebih buruk karena menghilangkan arti dari metode ini.
sumber