2010-12-03 12 views
1

Ich habe eine UITableView, die YouTube-Daten wie Videotitel und Datum anzeigt. Ich zeige auch eine UIWebView (75x75px) für jede UITableViewCell, die eine HTML-Zeichenfolge lädt.YouTube UITableView-Zellen mit UIWebView blockierendem Thread?

hier ist der zugehörige Code für - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath:

UIWebView *iconView = (UIWebView*)[cell.contentView viewWithTag:2]; 
[self embedYouTube:videoUrl frame:CGRectMake(0, 0, 75, 75) webView:iconView]; 

und die embedYouTube Funktion:

- (void)embedYouTube:(NSString*)url frame:(CGRect)frame webView:(UIWebView*)webView { 
if([loadedIconsArray containsObject:webView]) 
    return; 
    NSString *youTubeVideoHTML = @"<html><head>\ 
<body style=\"margin:0\">\ 
<embed id=\"yt\" src=\"%@\" type=\"application/x-shockwave-flash\" \ 
width=\"%0.0f\" height=\"%0.0f\"></embed>\ 
</body></html>"; 

    NSString *html = [NSString stringWithFormat:youTubeVideoHTML, url, frame.size.width, frame.size.height]; 

    [webView loadHTMLString:html baseURL:nil]; 
[loadedIconsArray addObject:webView]; 
} 

loadedIconsArray ist ein NSMutableArray

das Problem:

Wenn i lo Wenn ich meine YouTube-Ansicht anzeige, scheint der Hauptthread blockiert zu sein, während diese UIWebView Objekte den HTML-Code laden. Nach ein paar Sekunden funktioniert alles wie erwartet. Ich stelle fest, dass ich diese Verzögerung erst nach der ersten Installation der Anwendung erfahre. Alle anderen Application/View-Starts funktionieren einwandfrei.

Warum erfahre ich diese "Verzögerung" oder Thread-Blockierung?

Wie kann ich es vermeiden?

Antwort

-7

Jeder Netzwerkzugriff darf NICHT am Hauptthread erfolgen. Verwenden Sie die asynchrone API zum Laden von Inhalt. In der Zwischenzeit stellen Sie einfach ein einfaches Platzhalterbild/lokales Webview zur Anzeige bereit.

+0

Wie ich in meiner Antwort erwähnte, wird der Code in Frage nicht eine synchrone Netzwerk-Anforderung auf dem Haupt-Thread ausführen. –

+0

Ihr Code führt keinen synchronen Aufruf durch. Recht. Aber ich denke, dass das innere Objekt synchron geladen wird. Natürlich ist dies zu überprüfen. Sie könnten versuchen, zu sehen, wann die Auslastung mit einem UIWebView-Delegaten beginnt. –

3

Zunächst ist dies nicht ein Problem durch Netzwerkzugriff auf den Haupt-Thread verursacht (zumindest nicht Netzwerkzugriff, den Sie die Kontrolle haben). Die UIWebView-Methode, die für den Hauptthread aufgerufen wird, lautet loadHTMLString: baseURL :, wodurch die angegebene Zeichenfolge einfach als HTML-Inhalt in die Webansicht eingefügt wird. Der Inhalt der angegebenen HTML-Zeichenfolge impliziert eine Netzwerkanforderung an YouTube, die jedoch keine vom Benutzer initiierte Netzwerkanforderung für den Hauptthread erstellt, sondern nur auf einen Link in einer Webansicht klickt.

Jeder Vorschlag, diese Operation in einem Hintergrundthread auszuführen, ist falsch und wird höchstwahrscheinlich zu einem Absturz führen. Jede Interaktion mit einer Webansicht sollte im Hauptthread sein. iOS wird Ihnen einen Absturzfehler für das Instanziieren einer Webansicht auf einem Hintergrundthread sogar geben.

Leider, und hier liegt der Haken, es kann nichts gegen diese Verzögerung geben. Wenn UIWebView das Tag <embed> im angegebenen HTML-Code erkennt und feststellt, dass der Inhalt von YouTube stammen soll, wird ein nativer YouTube-Player-Prozess gestartet, um das Video abzuspielen. Die Verzögerung kann durch die Zeit verursacht werden, die der native Spieler zum Starten benötigt, weil der native Spieler YouTube kontaktiert. Dies kann durch Gnome verursacht werden, die im Keller des ursprünglichen Spielers leben. Ich kenne die Ursache nicht, und da der native Player ein völlig undurchsichtiger Prozess ist (kurz vor dem Jailbreak eines Geräts und in einigen Bibliotheken mit einem Disassembler), habe ich keinen guten Vorschlag, wie ich das herausfinden kann. Selbst wenn Sie es herausgefunden haben, gibt es fast sicher wenig zu nichts, was Sie dagegen tun könnten.

Ich weiß zu schätzen, dass dies eine unbefriedigende Antwort ist, und ich würde mich freuen, wenn jemand mir das Gegenteil beweisen würde.

+0

Ich bemerkte, dass, wenn Sie eine gültige URL-String für die BaseUrl enthalten, die Belastung viel schneller ist. also statt '[webView loadHTMLString: html baseURL: nil];' wäre es '[webView loadHTMLString: html baseURL: [NSURL URLWithString: @" http://google.com/ "]];' – binnyb

0

Ich bin mir nicht sicher, aber ich dachte, es könnte dir helfen, also dachte daran, diese Antwort zu posten ...

können Sie nur überprüfen und herausfinden, ob "webviewDidLoad" aufgerufen wird, wenn der Videoplayer die Verarbeitung des Videos beendet.

Wenn es wirklich aufruft, was ich empfehlen würde zu tun ist eine andere Sache zu erarbeiten, bis "webviewDidload" heißt, dass native Player stoppt die Verarbeitung des Videos wie youtube gibt ein sich drehendes weißes Rad, bis es das Video lädt, und dann das Display Webansicht.

Ich hoffe, ich habe ur Frage richtig verstanden und dies könnte u ein bisschen helfen ..

+1

Der loadHTMLString: baseURL : Die Methode ist nicht asynchron und initiiert daher keine Delegatenrückrufe. Wichtiger noch, es gibt einen wichtigen Unterschied zwischen der Webansicht, die ihren HTML-Inhalt lädt, und allen damit verbundenen Anfragen, die von Elementen im HTML initiiert werden. Die Webansicht ruft die Methode webViewDidFinishLoad: delegate auf, wenn sie den Dokumentkörper abgerufen hat. Dies bedeutet nicht, dass der Renderer damit fertig ist, dass JavaScript oder CSS vollständig interpretiert wurden oder dass referenzierter Inhalt (z. B. Bilder) heruntergeladen wurde. –

Verwandte Themen