3

In meiner Anwendung lade ich Informationen von mehreren (6-10) Websites mit NSXMLParser und lade dann die Informationen in Sichten.GCD geht zurück zum Hauptthread

Im Moment ist meine Anwendung so eingerichtet, dass sie die Websites in viewDidLoad in meinem Hauptansicht-Controller durchläuft und sie jeweils in einem von mir erstellten Hintergrundthread lädt. Dies geschieht in einem Hintergrundthread, sodass der Benutzer nicht auf das Laden aller Sites warten muss, bevor die Ansicht geladen wird.

for (NSMutableDictionary *dict in self.sitesArray) { 
    SiteData *data = [[SiteData alloc] init]; 
    [data setDelegate:self]; 
    dispatch_async(backgroundQueue, ^(void) { 
     [data loadSite:[dict objectForKey:@"SiteName"]]; 
    }); 

} 

In DATENDERSTANDORTE, lade ich die Seite mit NSXMLParser (alle der Delegatmethoden auch richtig implementiert)

-(void)loadSite:(NSString *)site{ 
    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:[self fullURLForSiteName:site]]; 
    [parser setDelegate:self]; 
    [parser parse]; 
    return; 
} 

Wenn die NSXMLParser das Dokument und die DATENDERSTANDORTE Instanz mit der Site Daten gefüllt ist abgeschlossen hat Es übergibt sich an eine Methode in meinem Hauptansicht-Controller auf dem Hauptthread.

- (void)parserDidEndDocument:(NSXMLParser *)parser{  
    dispatch_async(dispatch_get_main_queue(), ^(void) { 
     [delegate successfullyLoadedSite:self]; 
    }); 
} 

successfullyLoadedSite: laden die Daten der vergangenen Website in eine Ansicht und zeigt sich an den Benutzer. Beachten Sie, dass die Daten mehrerer Standorte auf demselben Bildschirm angezeigt werden.

Was ich passieren möchte: Ich möchte die Daten jeder Website auf dem Bildschirm angezeigt werden, wie es geladen ist, nicht warten müssen, bis alle von ihnen laden für die Ansicht zu aktualisieren beendet werden.

Was passiert: Einer der Standorte lädt und zeigt, dann muss ich warten, bis der Rest geladen ist, dann werden alle anderen auf einmal angezeigt.

Von der Konsolenprotokollierung scheint es, dass, sobald es das erste Mal successfullyLoadedSite: in der Hauptwarteschlange aufruft, alles in der Hauptwarteschlange ausgeführt wird. Nachdem die erste successfullyLoadedSite: in der Hauptwarteschlange aufgerufen wurde, werden alle Websites in Objekte geladen und anschließend in Ansichten geladen.

Irgendwelche Ideen, was ist los? Wenn du nicht weißt, dass ich neu im Multithreading bin. Thanks :)


Edit: Ich schaffe backgroundQueue wie folgt aus:

dispatch_queue_t backgroundQueue; 

und in init

backgroundQueue = dispatch_queue_create("uni.que.identifier.bgqueue", NULL); 

und lassen Sie ihn in dealloc mit:

dispatch_release(backgroundQueue); 
+0

Haben Sie bedeuten, dass 'loadSite:' auf dem Hintergrund ausgeführt wird, um das erste Mal, fädeln und dann immer auf dem Hauptthread? Ist 'backgroundQueue' eine serielle Warteschlange? Können Sie zeigen, wie Sie es erstellen? Zerstörst du es jemals? – Costique

+0

@Costique Ich habe diese Information an meine Frage angehängt.Tut mir leid, ich weiß nicht, ob es eine serielle Warteschlange ist oder nicht, aber ich bin sicher, dass du es sehen kannst. Ich bin mir fast sicher, dass 'loadSite:' auf einem Hintergrund Thread das erste Mal und dann immer auf den Haupt-Thread ausgeführt wird, aber ich bin nicht positiv. Kann ich das überprüfen? Vielen Dank. –

+0

So ist die Dispatch Queue nicht seriell. Setzen Sie NSLog (@ "% s", [NSThread isMainThread]? "Hauptthread": "Hintergrundthread"); 'in' loadSite: 'um sicherzustellen, dass es im Hintergrund ausgeführt wird, wie es sollte. Wann geben Sie die Versandwarteschlange frei? – Costique

Antwort

2

Die Warteschlange, in der die Funktion dispatch_queue_create zum Erstellen verwendet wird, ist die serielle Warteschlange, , dann wird dispatch_queue_create übergebener Block als sequenzielle Reihenfolge ausgeführt.

Verwendung:

dispatch_queue_t backgroundQueue = 
    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
+0

Ihr Vorschlag scheint so zu sein, als würde es funktionieren ... alle Dinge, die im Hauptthread erledigt werden, werden zur selben Zeit aufgerufen, aber ich denke, es ist nur so, weil alle Sites ungefähr zur gleichen Zeit geladen werden. Vielen Dank!! –