როდის უნდა გამოიყენოთ run loop iOS-ის განვითარებაში?
sobes.tech AI
პასუხი AI-სგან
Run loop უნდა გამოიყენოს, როდესაც საჭიროა მართოთ ნაკადის ქცევა, მისცემთ მას ელოდოს მოვლენებს და შეასრულოს შესაბამისი კოდი, ნაცვლად იმისა, რომ ის დაუყოვნებლივ დასრულდეს თავისი დავალების შესრულების შემდეგ. ეს კრიტიკულია:
-
მთავარი ნაკადი (Main Thread): Run loop-ი მთავარი ნაკადის ურთიერთქმედებას მართავს UIKit/AppKit-თან, მომხმარებლის მოვლენებს (კონტაქტები, კლიკები), ტაიმერებს, ქსელურ მოვლენებს და
performSelector:withObject:afterDelay:-ის გამოძახილებს. მისი გარეშე, აპლიკაცია ვერ შეძლებს რეაგირებას მომხმარებლის მოქმედებებზე და განაახლოს UI. -
მეორადი ნაკადები: როდესაც ფონური ნაკადი უნდა ასინქრონულად ასრულებდეს დავალებებს, უსმენს შემომავალ მონაცემებს (მაგალითად, სოკეტებს), პროცესებს სხვა ნაკადებიდან შეტყობინებებს ან იყენებს ტაიმერებს. ტიპიური სცენარები მოიცავს:
- სოკეტებთან მუშაობა.
- განმეორებადი დავალებების შესრულება ტაიმერით.
- შეტყობინებების მიღება და დამუშავება IPC-დან.
- ნაკადის სიცოცხლისუნარიანობის შენარჩუნება მომავალი მოთხოვნებისათვის, გარეშე მისი მუდმივი შექმნისა და განადგურების.
Run loop-ის გამოყენების მაგალითი მეორე ნაკადში შეიძლება იყოს ქსელური კავშირის შენარჩუნება:
// Swift-ში მაგალითი
class NetworkManager {
private let networkThread = Thread {
// კოდი ქსელური სესიის, სოკეტების და სხვა ინიციალიზაციისთვის
// წყაროს დამატება (მაგალითად, სოკეტი ან პორტი) run loop-ში
// CFRunLoopAddSource(CFRunLoopGetCurrent(), source, CFRunLoopMode.defaultMode)
// ტაიმერის დამატება, თუ საჭიროა
// CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.defaultMode)
// run loop-ის დაწყება. ის ბლოკავს ნაკადს, სანამ არ მიიღებს მოვლენას.
// .distantFuture - რომ run loop-ი არ დასრულდეს დაუყოვნებლივ
RunLoop.current.run()
// გაწმენდის კოდი, როდესაც run loop-ი დასრულდება
print("Network thread finishing")
}
func start() {
// გამოყენება `start()`-ის, ნაცვლად `detachNewThreadSelector`
// თანამედროვე მიდგომა
networkThread.start()
}
func stop() {
// სიგნალი run loop-ს, რომ უნდა დასრულდეს
// CFRunLoopStop(CFRunLoopGetCurrent()) // ან სპეციალური მოვლენის დამატება
// run loop ჩვეულებრივ დასრულდება, როდესაც მას არ აქვს წყაროები ან პირდაპირი გამოძახება
}
}
Run loop არ არის საჭირო იმ ნაკადებისთვის, რომლებიც ერთ დავალებას ასრულებენ და შემდეგ დასრულდებიან (მაგალითად, ერთჯერადი ოპერაციები ფონურ ნაკადში DispatchQueue.global().async-ის საშუალებით). ასეთ შემთხვევებში საკმარისია გამოიყენოთ Grand Central Dispatch (GCD).