【问题标题】:YouTube UITableView cells using UIWebView blocking thread?YouTube UITableView 单元格使用 UIWebView 阻塞线程?
【发布时间】:2010-12-03 16:26:08
【问题描述】:

我有一个 UITableView,它显示 YouTube 数据,例如视频标题和日期。我还为每个加载 HTML 字符串的 UITableViewCell 显示一个 UIWebView(75x75px)。

这里是- (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];

embedYouTube 函数:

- (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];
}

loadedIconsArrayNSMutableArray

问题:

当我加载我的 YouTube 视图时,似乎主线程被阻止,而这些 UIWebView 对象正在加载 HTML。几秒钟后,一切都按预期工作。我注意到我只有在第一次安装应用程序后才会遇到这种滞后。所有其他应用程序/视图启动工作正常。

为什么我会遇到这种“滞后”或线程阻塞?

如何避免?

【问题讨论】:

    标签: iphone objective-c ios uiwebview


    【解决方案1】:

    首先,这不是由主线程上的网络访问引起的问题(至少不是您可以控制的任何网络访问)。在主线程上调用的 UIWebView 方法是 loadHTMLString:baseURL:,它只是将指定的字符串作为其 HTML 内容填充到 Web 视图中。指定的 HTML 字符串的内容暗示了对 YouTube 的网络请求,但这不会在主线程上创建用户发起的网络请求,而不是在 Web 视图中单击链接。

    在后台线程中执行此操作的任何建议都是错误的,并且几乎肯定会导致崩溃。与 web 视图的任何交互都应该在主线程中;即使在后台线程上实例化 Web 视图,iOS 也会给您一个崩溃错误。

    不幸的是,问题就在这里,对于这种滞后,您可能无能为力。当 UIWebView 在指定的 HTML 中看到 &lt;embed&gt; 标记并确定内容来自 YouTube 时,它​​会启动一个原生 YouTube 播放器进程来播放视频。延迟可能是由于本地播放器启动时间造成的,可能是由于本地播放器联系 YouTube 造成的,也可能是由于住在本地播放器地下室的侏儒造成的。我不知道原因,并且由于本机播放器是一个完全不透明的过程(没有越狱设备并使用反汇编程序访问某些库),因此我对如何找出问题没有很好的建议。即使您确实发现了,也几乎可以肯定您无能为力。

    我很感激这是一个令人不满意的答案,我很乐意有人证明我错了。

    【讨论】:

    • 我注意到,如果您为baseUrl 包含一个有效的 URL 字符串,加载速度会快得多。所以不是`[webView loadHTMLString:html baseURL:nil];` 而是`[webView loadHTMLString:html baseURL:[NSURL URLWithString:@"google.com/"]];`
    【解决方案2】:

    我不确定这一点,但我认为它可能会帮助你考虑发布这个答案......

    你能检查一下视频播放器停止处理视频时是否调用了“webviewDidLoad”。

    如果它真的调用了我建议做的事情,那就是在调用“webviewDidload”之前做一些其他的事情,即原生播放器停止处理视频,就像 youtube 给出一个旋转的白轮,直到它加载视频,然后显示 webview .

    我希望我能正确理解你的问题,这可以帮助你一点..

    【讨论】:

    • loadHTMLString:baseURL: 方法不是异步的,因此它不会启动委托回调。更重要的是,加载其 HTML 内容的 Web 视图与由 HTML 中的元素发起的任何相关请求之间存在重要区别。 Web 视图在检索到文档正文时调用 webViewDidFinishLoad: 委托方法;这并不意味着渲染器已经完成了它,JavaScript 或 CSS 已经被完全解释,或者引用的内容(例如图像)已经下载。
    【解决方案3】:

    不得在主线程上进行任何网络访问。 使用异步 API 加载内容。同时只需提供一个简单的占位符图像/本地网络视图即可显示。

    【讨论】:

    • 正如我在回答中提到的,有问题的代码不会在主线程上执行同步网络请求。
    • 您的代码没有执行同步调用。对。但我认为内部对象将同步加载。当然,这是要检查的。您可以尝试使用 UIWebView 委托查看负载何时开始。
    猜你喜欢
    • 1970-01-01
    • 2012-05-16
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 2012-05-06
    • 1970-01-01
    • 1970-01-01
    • 2013-11-16
    相关资源
    最近更新 更多