2016-07-13 26 views
1

Wenn ich UI-Updates vom Hauptthread mache, scheinen sie nicht sofort wirksam zu werden. Das heißt, die Änderungen erscheinen nicht sofort auf dem Bildschirm.iOS UIView wird nicht sofort aktualisiert

Hier ist eine vereinfachte Version des Codes Ich bin mit:

- (void) do_ui_update { 
    // UI update here that does not appear immediately 
} 

- (void) some_time_consuming_function { 
    // line 1 
    // line 2 
    // ... 
    // line n 
} 

- (void) function_that_runs_in_main_thread { 
    [self RUN_ON_UI_THREAD:^{ 
     [self do_ui_update]; 

     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
      [self some_time_consuming_function]; 
     }); 
    }]; 
} 

- (void) RUN_ON_UI_THREAD:(dispatch_block_t)block 
{ 
    if ([NSThread isMainThread]) 
     block(); 
    else 
     dispatch_sync(dispatch_get_main_queue(), block); 
} 

Wenn die Debug-Haltepunkte an jeder Zeile in some_time_consuming_function, manchmal sind die UI-Updates auf dem Bildschirm angezeigt Einstellung, wenn der Debugger Linie 2 trifft, irgendwann Zeile 3 und so weiter.

Also meine Frage ist: Wie kann ich die UI-Updates auf dem Bildschirm erscheinen, bevor die erste Zeile von some_time_consuming_function erreicht wird?

+0

Das klingt für mich wie 'function_that_runs_in_main_thread' nicht immer auf der Haupt-Thread ist. Wenn Sie einen Breakpoint auf '[self do_ui_update]' setzen, ist es dann zu 100% im Hauptthread? – Swinny89

+0

können Sie Code anzeigen, der das function_that_runs_in_main_thread im Hauptthread ausführt? –

+0

Ich vermute, dass dies mit der Run-Schleife zusammenhängt. Die Ansicht wird erst am Ende der Runloop aktualisiert. Am besten ist es, wenn 'some_time_consuming_function' in einem Hintergrund-Thread läuft, um das Problem zu lösen. – Droppy

Antwort

1

den Versand der Hintergrund Versand in die nächste Haupt Schleifeniterationslatenzzeit:

-(void) function_that_runs_in_main_thread { 
    [self do_ui_update]; 

    dispatch_async(dispatch_get_main_queue(), ^{ 
     // All pending UI updates are now completed 
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
      [self some_time_consuming_function]; 
     }); 
    }); 
} 
+0

Danke Matten. Das funktioniert. Ich versuche jedoch zu verstehen, warum es funktioniert. Liegt es daran, dass ich zuvor einen asynchronen Prozess gestartet habe, der gestartet werden konnte, bevor die Hauptlaufschleife mit UI-Aktualisierungen beendet wurde, während jetzt der Async-Prozess der Hauptwarteschlange hinzugefügt wird und somit die UI-Aktualisierung als Erstes abgeschlossen wird? – Ash

+0

Ja. Ich kann mich nicht erinnern, ob es irgendwo dokumentiert ist, aber es hat immer so funktioniert. – Mats

Verwandte Themen