Adakah yang bisa menjelaskan untuk apa NSRunLoop
? jadi yang saya tahu NSRunLoop
apakah ada sesuatu yang berhubungan dengan NSThread
kan? Jadi asumsikan saya membuat seperti Thread
NSThread* th=[[NSThread alloc] initWithTarget:self selector:@selector(someMethod) object:nil];
[th start];
-(void) someMethod
{
NSLog(@"operation");
}
jadi setelah Thread ini menyelesaikan pekerjaannya kan? mengapa menggunakan RunLoops
atau di mana menggunakan? dari dokumen Apple Saya telah membaca sesuatu tetapi tidak jelas bagi saya, jadi harap jelaskan sesederhana mungkin
ios
objective-c
cocoa-touch
nsrunloop
taffarel
sumber
sumber
Jawaban:
Run loop adalah abstraksi yang (antara lain) menyediakan mekanisme untuk menangani sumber input sistem (soket, port, file, keyboard, mouse, timer, dll).
Setiap NSThread memiliki run loopnya sendiri, yang dapat diakses melalui metode currentRunLoop.
Secara umum, Anda tidak perlu mengakses run loop secara langsung, meskipun ada beberapa komponen (jaringan) yang memungkinkan Anda menentukan loop run mana yang akan mereka gunakan untuk pemrosesan I / O.
Run loop untuk thread tertentu akan menunggu hingga satu atau beberapa sumber inputnya memiliki beberapa data atau peristiwa, lalu mengaktifkan penangan input yang sesuai untuk memproses setiap sumber input yang "siap".
Setelah melakukannya, ia akan kembali ke loopnya, memproses masukan dari berbagai sumber, dan "tidur" jika tidak ada pekerjaan yang harus dilakukan.
Itu adalah deskripsi tingkat tinggi (mencoba menghindari terlalu banyak detail).
EDIT
Upaya untuk menanggapi komentar. Saya memecahnya menjadi beberapa bagian.
Memang. NSRunLoop bukanlah thread safe, dan hanya boleh diakses dari konteks thread yang menjalankan loop.
Jika Anda ingin memantau sebuah port, Anda cukup menambahkan port tersebut ke loop run, dan run loop akan mengawasi aktivitas port tersebut.
Anda juga dapat menambahkan timer secara eksplisit dengan
Run loop akan memproses semua event yang siap setiap iterasi (sesuai dengan modenya). Anda perlu melihat dokumentasi untuk mengetahui tentang mode jalan, karena itu sedikit di luar cakupan jawaban umum.
Di sebagian besar aplikasi, run loop utama akan berjalan secara otomatis. Namun, Anda bertanggung jawab untuk memulai putaran proses dan merespons peristiwa masuk untuk utas yang Anda putar.
Saya tidak yakin apa yang Anda maksud di sini. Anda tidak menambahkan acara ke run loop. Anda menambahkan sumber input dan sumber pengatur waktu (dari utas yang memiliki run loop). Run loop kemudian mengawasi mereka untuk aktivitas. Anda tentu saja dapat memberikan masukan data dari thread dan proses lain, tetapi masukan akan diproses oleh run loop yang memantau sumber-sumber tersebut di thread yang menjalankan loop jalan.
Memang. Nyatanya, run loop akan "tetap" di event handler sampai event handler itu kembali. Anda dapat melihat ini di aplikasi apa pun dengan cukup sederhana. Pasang penangan untuk setiap tindakan IO (mis., Menekan tombol) yang tidur. Anda akan memblokir loop proses utama (dan seluruh UI) hingga metode tersebut selesai.
Hal yang sama berlaku untuk semua run loop.
Saya sarankan Anda membaca dokumentasi berikut tentang run loop:
https://developer.apple.com/documentation/foundation/nsrunloop
dan bagaimana mereka digunakan dalam utas:
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW1
sumber
performSelector:onThread:withObject:waitUntilDone:
, meneruskanNSThread
objek dan pemilih Anda akan dijadwalkan di runloop utas itu.Mereka memungkinkan Anda untuk menunggu sampai pengguna mengetuk dan merespons sesuai, menunggu sampai Anda mendapatkan penyelesaianHandler dan menerapkan hasilnya, tunggu sampai Anda mendapatkan pengatur waktu dan melakukan suatu fungsi. Jika Anda tidak memiliki runloop maka Anda tidak dapat mendengarkan / menunggu ketukan pengguna, Anda tidak dapat menunggu sampai panggilan jaringan terjadi, Anda tidak dapat dibangunkan dalam x menit kecuali Anda menggunakan
DispatchSourceTimer
atauDispatchWorkItem
Juga dari komentar ini :
Khususnya tentang: "Thread latar belakang tidak memiliki runloopnya sendiri". Timer berikut gagal diaktifkan untuk pengiriman asinkron :
Saya pikir alasan
sync
blokir juga berjalan adalah karena:blok sinkronisasi biasanya dieksekusi dari dalam antrian sumbernya . Dalam contoh ini, antrian sumber adalah antrian utama, antrian apapun yang merupakan antrian tujuan.
Untuk menguji bahwa saya masuk ke
RunLoop.current
dalam setiap pengiriman.Pengiriman sinkronisasi memiliki runloop yang sama dengan antrean utama. Sedangkan RunLoop dalam blok async adalah instance yang berbeda dari yang lain. Anda mungkin berpikir bagaimana mengapa
RunLoop.current
mengembalikan nilai yang berbeda. Bukankah itu nilai bersama !? Pertanyaan bagus! Baca lebih lanjut:CATATAN PENTING:
The properti kelas
current
adalah TIDAK variabel global.Ini kontekstual. Itu hanya terlihat dalam cakupan utas yaitu Penyimpanan lokal- utas . Untuk lebih lanjut lihat di sini .
Ini adalah masalah umum dengan pengatur waktu. Anda tidak memiliki masalah yang sama jika Anda menggunakan
DispatchSourceTimer
sumber
RunLoops mirip seperti kotak tempat sesuatu terjadi begitu saja.
Pada dasarnya, dalam RunLoop, Anda pergi ke proses beberapa acara dan kemudian kembali. Atau kembalikan jika tidak memproses peristiwa apa pun sebelum batas waktu tercapai. Anda dapat mengatakannya sebagai mirip dengan NSURLConnections asynchronous, Memproses data di latar belakang tanpa mengganggu loop Anda saat ini dan tetapi pada saat yang sama, Anda memerlukan data secara sinkron. Yang dapat dilakukan dengan bantuan RunLoop yang membuat Anda asinkron
NSURLConnection
dan menyediakan data pada waktu panggilan. Anda dapat menggunakan RunLoop seperti ini:Dalam RunLoop ini, ini akan berjalan sampai Anda menyelesaikan beberapa pekerjaan Anda yang lain dan menyetel YourBoolFlag ke false .
Demikian pula, Anda dapat menggunakannya di utas.
Semoga ini bisa membantu Anda.
sumber
Dari sini
Dari sini
sumber