Kada naudoti run loop iOS kūrime?
sobes.tech AI
Atsakymas iš AI
Run loop turėtų būti naudojamas, kai reikia valdyti srauto elgseną, leidžiant jam laukti įvykių ir vykdyti atitinkamą kodą, vietoj to, kad jis iš karto baigtųsi po savo užduoties įvykdymo. Tai yra kritiška:
-
Pagrindinis srautas (Main Thread): Run loop pagrindiniame sraute apdoroja sąveiką su UIKit/AppKit, naudotojo įvykius (liesti, spustelėjimai), laikmačius, tinklo įvykius ir
performSelector:withObject:afterDelay:iškvietimus. Be jo, programa negalės reaguoti į naudotojo veiksmus ir atnaujinti UI. -
Antriniai srautai: Kai foninis srautas turi vykdyti asinchronines užduotis, klausytis įeinančių duomenų (pvz., lizdų), apdoroti žinutes iš kitų srautų arba naudoti laikmačius. Tipiniai scenarijai apima:
- Darbą su lizdais.
- Kartotinius užduočių vykdymą naudojant laikmačius.
- Žinučių gavimą ir apdorojimą iš IPC.
- Srauto gyvybingumo palaikymą būsimų užklausų apdorojimui be nuolatinio jo kūrimo ir naikinimo.
Pavyzdys, kaip naudoti run loop antriniame sraute, gali būti tinklo ryšio palaikymas:
// Pavyzdys Swift kalba
class NetworkManager {
private let networkThread = Thread {
// Kodo inicializacijai tinklo sesijai, lizdams ir pan.
// Šaltinio pridėjimas (pvz., lizdo ar porto) į run loop
// CFRunLoopAddSource(CFRunLoopGetCurrent(), source, CFRunLoopMode.defaultMode)
// Laikmačio pridėjimas, jei reikia
// CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.defaultMode)
// Run loop paleidimas. Jis blokuos srautą, kol gaus įvykį.
// .distantFuture – kad run loop nesibaigtų iš karto
RunLoop.current.run()
// Valymo kodas, kai run loop baigiasi
print("Network thread finishing")
}
func start() {
// Naudoti `start()` vietoj `detachNewThreadSelector`
// modernesnis požiūris
networkThread.start()
}
func stop() {
// Signaluoti run loop, kad jis turi baigtis
// CFRunLoopStop(CFRunLoopGetCurrent()) // arba pridėti specialų įvykį
// run loop paprastai baigiasi, kai nėra įvykio šaltinių arba pagal aiškų iškvietimą
}
}
Run loop nereikia tiems srautams, kurie atlieka vieną užduotį ir tada baigiasi (pvz., vienkartinės operacijos foniniame sraute per DispatchQueue.global().async). Tokiu atveju pakanka naudoti Grand Central Dispatch (GCD).