2016-04-06 12 views

Antwort

2

Die kurze Antwort ist "Ergebnisse sind undefiniert" oder "Schlechte Dinge". UIKit ist nicht Thread-sicher, also weißt du es nicht, aber es wird nicht gut.

Ich habe gesehen, Änderungen an der Benutzeroberfläche nehmen eine LOOOOOONNNG Zeit, wenn überhaupt, und ich habe Abstürze gesehen.

Die bessere Antwort ist "Tu das nicht."

+0

In ios 9 erhalten Sie eine Ausnahme, wenn Sie UI-Elemente in einem anderen Thread ändern – Paulw11

+0

@ Paulw11, Wirklich? Garantiert? Was ist der Mechanismus, der eine Ausnahme auslöst? –

+0

Sie erhalten eine Ausnahmebedingungsnachricht, die besagt "Sie ändern die Benutzeroberfläche in einem Hintergrundthread" – Paulw11

2

Es hängt davon ab, ob das Label in der View-Hierarchie ist oder nicht. Allgemeine Regel ist, dass der Code, der von einem Hintergrund-Thread ausgeführt wird, keine UI-Updates wie view.addSubview oder label.setNeedsLayout etc. auslösen sollte, dann ist es sicher, mit Ihrem Label in diesem Thread herumzuspielen.

Sie sollten jedoch vorsichtig sein, sobald Etikett zu einer Ansicht hinzugefügt wird, ist sogar die Aktualisierung label.text in einem Hintergrund Thread gefährlich, da es das Superview-Layout ungültig wird, so dass die Benutzeroberfläche in diesem Thread aktualisiert wird.

Ihre benutzerdefinierte UILabel Klasse sagen Lassen Sie einige Zeit tut in seinem Konstruktor aufwendige Operation, die nichts mit dem UI zu tun hat:

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

Dann können Sie dieses Label in einem separaten Thread initialisieren und fügen Sie in eine Ansicht in der Haupt (UI) Thread so die Interaktion des Benutzers mit der Benutzeroberfläche wird nicht blockiert werden:

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) 
    } 
} 

Lange Rede kurzen Sinn, können Sie neue UILabel initialisieren (oder jeden UIResponder) in einem Hintergrund-Thread Sie jedoch, sollte irgendeine seiner Eigenschaften ändern, die UI-Aktualisierung auslösen tes innerhalb des Hauptthreads.