2016-04-06 34 views
2

'daki arka plan iş parçacığına verirsek ne olur? Bu soruya bir röportajda soruldu. Arka plan iş parçacığına UILabel verirsek durumun ne olacağını bilmek istiyorum.UIlabel'i GCD veya NSOperationQueue

+0

UI öğelerinin yalnızca ana iş parçacığı üzerinde değiştirilmesi gerektiğine inanıyorum. http://stackoverflow.com/a/7905497/4475605 – Adrian

+0

UILabel ile ne yapmaya çalıştığınıza bağlı. – rmaddy

cevap

2

Kısa cevap "sonuçlar tanımsız" veya "Kötü şeyler" dir. UIKit iş parçacığı değildir, bu yüzden bilmiyorsunuz, ama iyi olmayacak.

UI değişikliklerini, etkilenmek için LOOOOOONNNG süresi aldım ve çökmeleri gördüm.

Daha iyi cevap "Bunu yapma."

+0

ios 9'da, UI öğelerini başka bir iş parçacığında değiştirirseniz bir istisna olacaksınız. – Paulw11

+0

@ Paulw11, Really? Garantili? Bir istisna atar mekanizma nedir? –

+0

"Bir arka plan iş parçacığında UI'yi değiştiriyorsunuz" gibi bir özel durum iletisi alıyorsunuz. – Paulw11

2

Etiketin görünüm hiyerarşisinde olup olmamasına bağlıdır. Genel kural, bir arka plan iş parçacığı tarafından çalıştırılan kodun, view.addSubview veya label.setNeedsLayout vb. Gibi herhangi bir UI güncelleştirmesini tetiklememesi gerektiğidir, ardından bu iş parçacığındaki etiketinizle oynamak güvenlidir.

Dikkatli olmalısınız, etiket bir kez görünümüne eklendiğinde, arka plan iş parçacığında label.text numaralı güncelleştirmenin güncellenmesi bile süper görüntü düzenini geçersiz kılacağından tehlikelidir, böylece kullanıcı arabirimi bu iş parçacığı içinde güncellenir.

en özel UILabel sınıf UI ile ilgisi yoktur onun kurucu operasyonu tüketen biraz zaman yapıyor diyelim

: Sonra

class MyFatLabel: UILabel { 
    override init(frame: CGRect) { 
    super.init(frame: frame) 
    self.text = "Lorem ipsum"   
    self.readDataFromDisk() // will block the main thread. 
    } 
} 

, ayrı bir iş parçacığı bu etiketi başlatmak ve içine ekleyebilirsiniz UI ile kullanıcı etkileşimi bloke olmayacak şekilde ana (UI) Dizideki bir görünüm:

dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)) { 
    let label = MyFatLabel(frame: CGRectZero) 

    dispatch_async(dispatch_get_main_queue()) { 
    view.addSubview(label) 
    } 
} 

Uzun lafın kısası, sen ancak bir arka plan iplik sizi yeni UILabel (veya herhangi UIResponder) başlatabilir UI upda'yı tetikleyen özelliklerinden herhangi birini değiştirmeli ana iş parçacığı içinde tes.