UIWebView正在加载HTML5视频时出现EXC_BAD_ACCESS崩溃

7
在我们的iPad应用程序中,我们使用UIWebView从一个域加载不同的网站,其中一些网站包含hml5视频。没有视频的网站可以完美地加载。但是当我加载包含htmlt5视频的网站时,我的应用程序在UIWebView的加载过程中有时会崩溃并显示EXC_BAD_ACCESS,有时则不会。每当发生这样的崩溃时,似乎都发生在将视频播放器添加到网站的位置。
我从Apple下载了UICatalog示例,并只更改了WebViewController类中的默认URL为包含html5-video的网站的URL。结果相同……有时崩溃,有时不崩溃。
我还在Xcode上创建了一个新项目(基于视图的应用程序-针对iPad),并仅向新项目的ViewController中添加了一个UIWebView。同样……加载包含html5-video的网站有时会导致崩溃,有时则不会。
“新项目”ViewController的代码(实现):
- (void)viewDidLoad {
    [super viewDidLoad];

    self.myWebView = [[[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 768, 1004)] autorelease];
    self.myWebView.backgroundColor = [UIColor whiteColor];
    self.myWebView.scalesPageToFit = YES;
    self.myWebView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
    self.myWebView.delegate = self;
    [self.view addSubview: self.myWebView];

    [self.myWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.gelbeseiten.de/129103114849"]]];

    //More Sites with HTML5-Videos ...
    //[self.myWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.gelbeseiten.de/129103746403"]]];
    //[self.myWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.gelbeseiten.de/129105233646"]]];
}

- (void)viewDidUnload {
    [super viewDidUnload];

    self.myWebView = nil;
}

- (void)viewWillDisappear:(BOOL)animated {
    [self.myWebView stopLoading];
}

- (void)dealloc {
    myWebView.delegate = nil;
    [myWebView release];

    [super dealloc];
}

"新项目"视图控制器(标题)中的代码:

@interface WebViewTestViewController : UIViewController <UIWebViewDelegate> {
    UIWebView *myWebView;
}

@property (nonatomic, retain) UIWebView *myWebView;

设备日志:

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x00000098
Crashed Thread:  0

Thread 0 Crashed:
0   WebCore                         0x34c7d09e WebCore::RenderLayer::clippingRoot() const + 110
1   WebCore                         0x34c7cf2a WebCore::RenderLayer::childrenClipRect() const + 26
2   WebCore                         0x34c7ce0c WebCore::RenderWidget::setWidgetGeometry(WebCore::IntRect const&) + 40
3   WebCore                         0x34c5e0f8 WebCore::RenderWidget::updateWidgetPosition() + 320
4   WebCore                         0x34ba0170 WebCore::RenderView::updateWidgetPositions() + 144
5   WebCore                         0x34b97d16 WebCore::FrameView::performPostLayoutTasks() + 202
6   WebCore                         0x34b8a6c0 WebCore::FrameView::layout(bool) + 2116
7   WebCore                         0x34bc5244 WebCore::FrameView::forceLayout(bool) + 4
8   WebKit                          0x302c0c24 -[WebHTMLView layoutToMinimumPageWidth:height:maximumPageWidth:adjustingViewSize:] + 136
9   WebKit                          0x302c0b8e -[WebHTMLView layout] + 18
10  WebKit                          0x302c26f2 -[WebHTMLView(WebInternal) _layoutIfNeeded] + 50
11  WebKit                          0x302c2622 -[WebHTMLView(WebInternal) _web_layoutIfNeededRecursive] + 14
12  WebKit                          0x302c251e -[WebHTMLView(WebPrivate) viewWillDraw] + 50
13  CoreFoundation                  0x3581dfc0 -[NSObject(NSObject) performSelector:] + 12
14  CoreFoundation                  0x35826d4a -[NSArray makeObjectsPerformSelector:] + 382
15  WebCore                         0x34bb000c -[WAKView viewWillDraw] + 24
16  CoreFoundation                  0x3581dfc0 -[NSObject(NSObject) performSelector:] + 12
17  CoreFoundation                  0x35826d4a -[NSArray makeObjectsPerformSelector:] + 382
18  WebCore                         0x34bb000c -[WAKView viewWillDraw] + 24
19  CoreFoundation                  0x3581dfc0 -[NSObject(NSObject) performSelector:] + 12
20  CoreFoundation                  0x35826d4a -[NSArray makeObjectsPerformSelector:] + 382
21  WebCore                         0x34bb000c -[WAKView viewWillDraw] + 24
22  CoreFoundation                  0x3581dfc0 -[NSObject(NSObject) performSelector:] + 12
23  CoreFoundation                  0x35826d4a -[NSArray makeObjectsPerformSelector:] + 382
24  WebCore                         0x34bb000c -[WAKView viewWillDraw] + 24
25  WebKit                          0x302c24cc -[WebView(WebPrivate) viewWillDraw] + 56
26  WebCore                         0x34bafec0 WebCore::TileCache::prepareToDraw() + 36
27  WebCore                         0x34bafe6e -[TileLayer display] + 26
28  QuartzCore                      0x31079fb0 CALayerDisplayIfNeeded + 176
29  QuartzCore                      0x3106f56e CA::Context::commit_transaction(CA::Transaction*) + 214
30  QuartzCore                      0x3106f37c CA::Transaction::commit() + 184
31  QuartzCore                      0x31092f96 CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 46
32  CoreFoundation                  0x3580ac52 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 10
33  CoreFoundation                  0x3580aac6 __CFRunLoopDoObservers + 406
34  CoreFoundation                  0x358020c4 __CFRunLoopRun + 848
35  CoreFoundation                  0x35801c80 CFRunLoopRunSpecific + 224
36  CoreFoundation                  0x35801b88 CFRunLoopRunInMode + 52
37  GraphicsServices                0x320c84a4 GSEventRunModal + 108
38  GraphicsServices                0x320c8550 GSEventRun + 56
39  UIKit                           0x341dc322 -[UIApplication _run] + 406
40  UIKit                           0x341d9e8c UIApplicationMain + 664
41  WebViewTest                     0x00002c24 0x1000 + 7204
42  WebViewTest                     0x00002bd8 0x1000 + 7128

有人能给我提供一个想法吗?

先行致谢,Florian

5个回答

2

有一个小技巧可以避免这个崩溃。如果在视频内容加载之前稍微滚动一下webview,就可以避免崩溃。在尝试从代码中实现之前,用手指在设备上稍微滚动一下webView,现在它不会崩溃了。

在代码中,可以像这样做:

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
  [webView stringByEvaluatingJavaScriptFromString:@"window.scrollTo(0, 10);"];
}

通过JavaScript模拟Webview上的滚动。滚动值可以尽可能低,以至于用户完全不会注意到滚动。


1
告诉webview在webViewDidFinishLoad:上评估任何JavaScript(或完全不评估)似乎可以工作(虽然有点hacky)。
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
  [webView stringByEvaluatingJavaScriptFromString:@""];
}

1

看起来我解决了这个问题... 我把所有HTML-5视频标签的插入都移到了Javascript中

function placeVideoTag() {
   var val = '<video />';
   var el = document.getElementById('video-id');
   el.innerHTML = val;
}

我正在 [UIWebView didFinishLoad] 中调用JS

- (void)webViewDidFinishLoad:(UIWebView *)aWebView {
   [aWebView stringByEvaluatingJavaScriptFromString:@"placeVideoTag()"];
}

在我的情况下完美运作。 其他建议对我没有用。


这个方法解决了我在iOS 8.1.3上遇到的同样问题!!! 添加视频标签会导致我的应用程序崩溃,现在我只需调用placeVideoTag,应用程序就不会再崩溃了!!! 真不敢相信这种退化。 我所有的问题都与此相同:https://dev59.com/JV8d5IYBdhLWcg3wlzD6 - Giorgio Andretti

0

感谢您的帖子!!!在我的情况下,iPad 的纵向和横向模式只能使用不同的相当高的偏移值才能正常工作

(纵向模式:大于60;横向模式:大于780):

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    if (self.interfaceOrientation == UIInterfaceOrientationPortrait ||
    self.interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {

        [webView stringByEvaluatingJavaScriptFromString:@"window.scrollTo(0, 60);"];
    } else if (self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
           self.interfaceOrientation == UIInterfaceOrientationLandscapeRight) {

        [webView stringByEvaluatingJavaScriptFromString:@"window.scrollTo(0, 780);"];
    }
    webView.loadCounter--;
}

但是使用这种解决方案,我的应用程序在加载网站期间双击缩放时会崩溃。

我已经子类化了UIWebView来解决这个问题(防止webView在加载时缩放):

.m:

@synthesize loadCounter;

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    CGPoint p = currentPoint;
    NSTimeInterval t = currentTimestamp;
    currentPoint = point;
    currentTimestamp = [event timestamp];

    if (CGPointEqualToPoint(p, point) &&
        [event timestamp] - t < 0.2 && loadCounter > 0){
        return self.superview;
    }

    return [super hitTest:point withEvent:event];
}

.h:

@interface NonDoubleTapableWhileLoadingWebView : UIWebView {
    CGPoint currentPoint;
    NSTimeInterval currentTimestamp;

    NSInteger loadCounter;
}

@property (assign) NSInteger loadCounter;

并添加了一个计数器来确定最后一次“didFinish”调用,并重新激活双击功能(将loadCounter初始化为0)

- (void)webViewDidStartLoad:(UIWebView *)webView {
    linkWebView.loadCounter++;
}

0

我正好遇到了同样的问题,还没有答案。看到许多其他人报告了类似的问题-只有iOS 4.2.1。

基本上,我有一个UIView控制器,其中包含一个webview作为其子视图,并加载URLRequest到youtube链接。

第一次加载viewController时,控制台记录错误“无法读取/ Developer / Platforms / iPhoneOS.platform / DeviceSupport / 4.2.1(8C148)/ Symbols / System / Library / Internet插件/ QuickTime Plugin.webplugin / QuickTime Plugin的符号(未找到文件)。 “我停止加载并释放viewController。第二次重新加载具有相同请求的新viewController到该YouTube链接,现在应用程序崩溃并出现EXC_BAD_ACCESS错误。


这似乎是iOS 4.2.1的问题。使用iOS 3.2.2进行测试没有问题。刚刚阅读了下一个iOS 4.3的发布说明:“Web-修复了导致Safari和其他应用程序在加载某些重型网站后崩溃的问题。”可能问题已经在iOS 4.3中得到解决。 - Florian
@Florian 你说得对!问题已经通过升级到适用于iOS 4.3的Xcode 3.2.6解决了。我为了等待这个版本,已经将应用程序的升级推迟了两周... - xingzhi.sg
2
哦,我的错误,它在Xcode 3.2.6的iOS 4.3中没有解决...只是因为我太兴奋了,在加载之前就把它拖过去了,正如Srijith Vijayamohan建议的那样。最终我通过Srijith Vijayamohan的建议解决了这个问题。谢谢。 - xingzhi.sg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接