问题
in our iPad-App we are using an UIWebView to load different sites from one domain some of them with a hml5-Video. Sites without a Video do load perfectly. But when I'm loading a site containing htmlt5-video sometimes my app crashes during the loading-process of the UIWebView with EXC_BAD_ACCESS and sometimes it does not. Whenever such a crash occurs it seems to happen at the point where the Video-Player is added into the site.
I did download the UICatalog-Example from Apple and just did change the Default-URL in the WebViewController-Class to a URL of a site containg html5-video. Same results ... sometimes crash sometimes no crash.
I also did create a New Project on Xcode (View-based Application - for iPad) and only did add a UIWebView to the new Projects ViewController. Again ... loading a site containing html5-video sometimes leads to a crash and sometimes not.
CODE FROM "NEW PROJECTS" VIEWCONTROLLER (IMPLEMENTATION):
- (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];
}
CODE FROM "NEW PROJECTS" VIEWCONTROLLER (HEADER):
@interface WebViewTestViewController : UIViewController <UIWebViewDelegate> {
UIWebView *myWebView;
}
@property (nonatomic, retain) UIWebView *myWebView;
DEVICE LOGS:
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
Can anybody give me an idea?
Thanks in advance, Florian
回答1:
There is a little trick to override this crash. If you slightly scroll the webview just before the video content is loaded, the crash can be avoided. Before trying it out from code, try scrolling the webView a bit on device with your finger. It won't crash now.
In code, do something like this:
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
[webView stringByEvaluatingJavaScriptFromString:@"window.scrollTo(0, 10);"];
}
to simulate a scroll on the webview through javascript. The scroll value can be as low as 1, so the user won't notice the scroll at all.
回答2:
Telling the webview to evaluate any JavaScript (or none at all) on webViewDidFinishLoad: seems work (albeit hacky).
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
[webView stringByEvaluatingJavaScriptFromString:@""];
}
回答3:
Seems I've solved this issue... i've moved all HTML-5 video tags insertion in Javascript
function placeVideoTag() {
var val = '<video />';
var el = document.getElementById('video-id');
el.innerHTML = val;
}
And i'm calling JS in [UIWebView didFinishLoad]
- (void)webViewDidFinishLoad:(UIWebView *)aWebView {
[aWebView stringByEvaluatingJavaScriptFromString:@"placeVideoTag()"];
}
Works perfectly in my case. Other suggestions didn't work for me.
回答4:
I have exactly the same problem. no answer yet. Saw many others reports similar problems - iOS 4.2.1 only.
Basically, I have a UIView Controller with a webview as its subview, and load a URLRequest to a youtube link.
The first time I load the viewController, the console logs error "Unable to read symbols for /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.2.1 (8C148)/Symbols/System/Library/Internet Plug-Ins/QuickTime Plugin.webplugin/QuickTime Plugin (file not found).". I stop loading and release the viewController. The second time I re-load new viewController with the same request to that youtube link, now the app crashed with EXC_BAD_ACCESS
回答5:
Thanks, for your posts!!! In my case it only works with different quite high offset-values for Portrait- and Landscape-Mode on iPad
(Portrait-Mode: greater than 60; Landscape-Mode: greater than 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--;
}
But with this solution my app crashes by double-tapping to zoom during the loading-process of a site.
I did subclass UIWebView to solve this problem (to prevent webView from zooming while loading):
.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;
And added a counter to determine the last "didFinish"-call and to reactivate the double-tapping possibility (init loadCounter with 0)
- (void)webViewDidStartLoad:(UIWebView *)webView {
linkWebView.loadCounter++;
}
来源:https://stackoverflow.com/questions/5027876/uiwebview-loading-html5-video-exc-bad-access-crash