Sobes.tech
Middle+

iOS geliştirmede run loop ne zaman kullanılmalı?

sobes.tech yapay zeka

AI'dan gelen yanıt

Run loop, bir akışın davranışını yönetmek, olayları beklemesine izin vermek ve ilgili kodu çalıştırmak gerektiğinde kullanılmalıdır; böylece işlem, görevini tamamladıktan sonra hemen sona ermez. Bu, aşağıdaki durumlar için kritiktir:

  1. Ana akış (Main Thread): Ana akışın run loop'u UIKit/AppKit ile etkileşimi, kullanıcı olayları (dokunuşlar, tıklamalar), zamanlayıcılar, ağ olayları ve performSelector:withObject:afterDelay: çağrılarını işler. Onu olmadan, uygulama kullanıcı eylemlerine yanıt veremez ve UI'yi güncelleyemez.

  2. İkincil akışlar: Arka planda çalışan bir akış, asenkron görevleri yerine getirmeli, gelen verileri dinlemeli (örneğin, soketler), diğer akışlardan mesajlar işlemiş veya zamanlayıcılar kullanmalıdır. Tipik senaryolar şunları içerir:

    • Soketlerle çalışma.
    • Zamanlayıcı ile tekrarlayan görevlerin yürütülmesi.
    • IPC (İşlemlerarası iletişim) mesajlarının alınması ve işlenmesi.
    • Gelecekteki istekleri işlemek için akışı canlı tutmak, sürekli oluşturup yok etmek yerine.

Bir ikincil akışta run loop kullanımına örnek, ağ bağlantısının sürdürülmesidir:

// Swift'te örnek
class NetworkManager {
    private let networkThread = Thread {
        // Ağ oturumu, soketler vb. başlatma kodu

        // Olay kaynağı ekleme (örneğin, soket veya port) run loop'a
        // CFRunLoopAddSource(CFRunLoopGetCurrent(), source, CFRunLoopMode.defaultMode)

        // Gerekirse zamanlayıcı ekleme
        // CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.defaultMode)

        // Run loop'u başlat. Bu, olay alınana kadar akışı engeller.
        // .distantFuture - böylece run loop hemen sona ermez
        RunLoop.current.run()

        // Run loop sona erdikten sonra temizleme kodu
        print("Ağ akışı sona erdi")
    }

    func start() {
        // `start()` kullanmak, `detachNewThreadSelector` yerine
        // daha modern bir yaklaşım
        networkThread.start()
    }

    // Diğer akıştan run loop'u durdurmak için metod
    func stop() {
        // Run loop'un sona ermesi için sinyal gönder
        // CFRunLoopStop(CFRunLoopGetCurrent()) // veya özel bir olay eklenebilir
        // Run loop genellikle olay kaynağı kalmadığında veya açıkça stop çağrıldığında sona erer
    }
}

Run loop, bir görev yapan ve sonra biten akışlar için gerekli değildir (örneğin, DispatchQueue.global().async ile yapılan tek seferlik arka plan işlemleri). Bu durumda, Grand Central Dispatch (GCD) kullanmak yeterlidir.