2012-06-20 3 views
16

Ich weiß, dass UIView nicht threadsicher ist, daher kann ich keine Ansicht auf einen Hintergrundthread hinzufügen. Um das zu umgehen, ist es in Ordnung, eine UIView in einem Hintergrundthread zu erstellen und dann im Hauptthread hinzuzufügen?Ist es in Ordnung, eine UIView auf einem Hintergrund-Thread zu erstellen?

Hinweis: Der Grund, warum ich dies nicht im Hauptthread mache, ist, weil mein tatsächlicher Code viel komplexer ist und daher eine Weile dauert, um alle Ansichten zu erstellen und die Werte zu füllen. Ich möchte nicht, dass die Benutzeroberfläche unpassend wird, wenn ich das tue, also versuche ich, dies zu umgehen.

zum Beispiel ..

-(void)addLabel//called on background thread 
{ 
    UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(0,0,40,100)]; 
    [label setText:@"example"] 
    [self.view performSelector:@selector(addSubview:) onThread:[NSThread mainThread] withObject:example waitUntilDone:YES]; 
} 

Vielen Dank im Voraus.

+0

Ich glaube, Sie haben es richtig. Erstellen Sie es im Hintergrund, aber aktualisieren Sie die Benutzeroberfläche im Hauptfenster. –

Antwort

15

Von UIView:

Threading Überlegungen

Manipulations zu Ihrer Anwendung Benutzeroberfläche auf dem Hauptthread erfolgen muss. Daher sollten Sie die Methoden der UIView-Klasse immer aus Code aufrufen, der im Hauptthread Ihrer Anwendung ausgeführt wird. Die einzige Zeit, die dies nicht unbedingt erforderlich ist, ist beim Erstellen des Ansichtsobjekts selbst, aber alle anderen Manipulationen sollten im Hauptthread erfolgen.

Der Aufruf an initWithFrame: ist explizit nicht threadsicher. Der Aufruf an setText: ist wahrscheinlich nicht threadsicher und fällt unter die "Manipulations" -Klausel. Diese sind sicherlich nicht fadensicher.

Tun Sie Ihre Arbeit, um herauszufinden, die Daten auf einem Hintergrund-Thread. Erstellen Sie dann Ihre Ansichten zum Hauptthread. Wenn eine große Anzahl von Ansichten vorhanden ist, können Sie versuchen, die Arbeit unter Verwendung mehrerer dispatch_async()-Aufrufe in die Hauptwarteschlange aufzuteilen. Dadurch kann die Benutzeroberfläche reagieren. Ich habe nicht ausführlich damit experimentiert.

Sie sollten auch erwägen, möglichst von UIView zu CALayer zu wechseln. Die meisten CALayer Arbeiten können auf Hintergrundthreads durchgeführt werden. Wenn Sie eine große Anzahl von Ansichten haben, ist das wahrscheinlich sowieso ineffizient. Wenn es nur sehr lange dauert, die Daten für die Ansichten zu berechnen, deutet dies darauf hin, dass Sie Modell- und Ansichtsinformationen nicht ordnungsgemäß trennen. Die Model-Klassen sollten alles berechnen, was unabhängig von der Erstellung der Ansichten benötigt wird.

+5

Es tut mir leid, aber könnten Sie Ihre Antwort klären ? Das Zitat von Apple sagt ausdrücklich, dass das Erstellen einer Ansicht im Hintergrund okay ist, aber du sagst, dass es nicht so ist. Warum? –

+0

@iamataptool wahrscheinlich können Sie UIView sicher mit 'init'-Methode, aber nicht mit' initWithFrame: 'Methode erstellen? – DanSkeel

+0

Der CALayer Tipp machte meinen Tag und meine Woche. Danke vielmals! –

0

Die Drawing and Printing Guide Zustände:

Wichtig Die UIKit Klassen sind in der Regel nicht Thread-sicher. Alle zeichnungsbezogenen Vorgänge sollten im Hauptthread Ihrer Anwendung ausgeführt werden.

So, wie ich das verstehe, scheint es, dass das einzige Problem mit "Zeichnung bezogenen Operationen" zusammenhängt. Wenn wir davon ausgehen, dass eine korrekte Klasse nur solche Operationen in ihrer drawRect: Methode ausführt, sollte die von Ihnen vorgeschlagene Methode in Ordnung sein.

+0

In meinem Fall wacht meine App über 'UIApplicationLaunchOptionsLocalNotificationKey' auf, also ist sie im Hintergrund. Ist es in Ordnung, wenn ich Subview-Ergänzungen mache, wenn die App im Hintergrund ist? https://stackoverflow.com/questions/46584566/how-to-stop-handle-ui-operations-in-ios-when-app-moves-to-background-state – Nil

3

Ich verwende Xcode Version 9.0 Beta 3 (9M174d), eine Warnung erhalten.

[UView init] darf nur vom Haupt-Thread aufgerufen werden

Also ich denke, Sie UI in Haupt-Thread erstellen sollte besser

zeigen das Bild unten:

enter image description here

Verwandte Themen