UIWebDocumentView _updateSubviewCaches在iOS10中崩溃 [英] UIWebDocumentView _updateSubviewCaches crash in iOS10

查看:3132
本文介绍了UIWebDocumentView _updateSubviewCaches在iOS10中崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在iOS10中更严重地在HockeyApp中遇到以下崩溃。



第4行发生错误:

  0 libobjc.A.dylib 0x0000000187242f30 objc_msgSend + 16 
1的UIKit 0x000000018e86e914 - [UIWebDocumentView _updateSubviewCaches] + 36
2的UIKit 0x000000018e69093c - [UIWebDocumentView子视图] + 88
3的UIKit 0x000000018e941bd4 - [UIView的(CALayerDelegate)_wantsReapplicationOfAutoLayoutWithLayoutDirtyOnEntry:] + 68
4 UIKit的0x000000018e63d770 - [UIView的(CALayerDelegate)layoutSublayersOfLayer:] + 1248
5 QuartzCore 0x000000018bb0640c - [CALayer的layoutSublayers] + 144
6 QuartzCore 0x000000018bafb0e8 CA ::层:: layout_if_needed(CA ::交易*)+ 288
7 QuartzCore 0x000000018bafafa8 CA ::层:: layout_and_display_if_needed(CA ::交易*)+ 28
8 QuartzCore 0x000000018ba77c64 CA ::语境:: commit_transaction (CA ::交易*)+ 248
9 QuartzCore 0x000000018ba9f0d0 CA ::交易::提交()+ 508
10 QuartzCore 0x000000018ba9faf0 CA ::交易:: observer_callback(__ CFRunLoopObserver *,无符号长,无效* )+ 116
11的CoreFoundation 0x00000001887a57dc __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 28
12的CoreFoundation 0x00000001887a340c __CFRunLoopDoObservers + 368
13的CoreFoundation 0x00000001886d2068 CFRunLoopRunSpecific + 472
14的WebCore 0x000000018d273a2c RunWebThread(无效*)+ 452
15分配libsystem_pthread.dylib 0x000000018788b860 _pthread_body + 236
16 libsystem_pthread.dylib 0x000000018788b770 _pthread_start + 280
17 libsystem_pthread.dylib 0x0000000187888dbc thread_start + 0

任何想法这里发生了什么?
看起来像以下崩溃组也是相关的。



崩溃组1

  [UIWebBrowserView _collectAdditionalSubviews] 
objc_msgSend()选择器名称:autorelease

崩溃组2

  [UIWebDocumentView子视图] 
objc_msgSend ()selector name:arrayByAddingObjectsFromArray:


解决方案我自己的问题,因为我能够复制这个问题,找到根本原因。



请不要以下。



1。我使用UIWebView。首先,不建议这样做。



2。以下实施方式导致此问题。我在这里写一个伪代码来演示这个问题。

  @implementation MyViewController 

- (void)loadView {

//创建UIWebView这里
self.webView = [[UIWebView alloc] initWithFrame:_some_frame];

//此处设置Web视图属性。

//添加到视图
[self.view addSubView:self.webView];

[self populateWebView];
}

- (void)populateWebView {
[self.webView loadHTMLString:_some_html
baseURL:[NSURL fileURLWithPath:_some_path]];
}


- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];

if(self.webView){
//以下两行引起此问题。
self.webView.scrollView.contentInset = _some_insets;
self.webView.scrollView.scrollIndicatorInsets = _some_insets;
}
}

@end

strong> 3。下面给出了解决方案。

  @implementation MyViewController 

- {

//创建UIWebView这里
self.webView = [[UIWebView alloc] initWithFrame:_some_frame];

//此处设置Web视图属性。

//添加到视图
[self.view addSubView:self.webView];

[self populateWebView];
}

- (void)populateWebView {
[self.webView loadHTMLString:_some_html
baseURL:[NSURL fileURLWithPath:_some_path]];
}


- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
}

- (void)webViewDidFinishLoad:(UIWebView *)webView {
webView.scrollView.contentInset = _some_insets;
webView.scrollView.scrollIndicatorInsets = _some_insets;
}

@end

在我的实际代码中,I在这里通过子类化 UIWebView 来使用自定义WebView类。不认为会造成一些问题。根本原因是在 viewDidLayoutSubviews 中设置 contentInset scrollIndicatorInsets ,这不是一个好主意。当我放置断点时, viewDidLayoutSubviews 调用了几次,最终导致App崩溃。



作为一个解决方案,我将代码的以下部分移动到 webViewDidFinishLoad ,并且只有当WebView完成加载。因此,请在这个委托方法下添加这些代码。

  webView.scrollView.contentInset = _some_insets; 
webView.scrollView.scrollIndicatorInsets = _some_insets;


I am getting the following crash in HockeyApp more seriously in iOS10. Please find the crash log as given below.

Thread 4 Crashed:

0 libobjc.A.dylib 0x0000000187242f30 objc_msgSend + 16
1 UIKit 0x000000018e86e914 -[UIWebDocumentView _updateSubviewCaches] + 36
2 UIKit 0x000000018e69093c -[UIWebDocumentView subviews] + 88
3 UIKit 0x000000018e941bd4 -[UIView(CALayerDelegate) _wantsReapplicationOfAutoLayoutWithLayoutDirtyOnEntry:] + 68
4 UIKit 0x000000018e63d770 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1248
5 QuartzCore 0x000000018bb0640c -[CALayer layoutSublayers] + 144
6 QuartzCore 0x000000018bafb0e8 CA::Layer::layout_if_needed(CA::Transaction*) + 288
7 QuartzCore 0x000000018bafafa8 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 28
8 QuartzCore 0x000000018ba77c64 CA::Context::commit_transaction(CA::Transaction*) + 248
9 QuartzCore 0x000000018ba9f0d0 CA::Transaction::commit() + 508
10 QuartzCore 0x000000018ba9faf0 CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 116
11 CoreFoundation 0x00000001887a57dc __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 28
12 CoreFoundation 0x00000001887a340c __CFRunLoopDoObservers + 368
13 CoreFoundation 0x00000001886d2068 CFRunLoopRunSpecific + 472
14 WebCore 0x000000018d273a2c RunWebThread(void*) + 452
15 libsystem_pthread.dylib 0x000000018788b860 _pthread_body + 236
16 libsystem_pthread.dylib 0x000000018788b770 _pthread_start + 280
17 libsystem_pthread.dylib 0x0000000187888dbc thread_start + 0

Any idea what is going on here ? Seems like the following crash groups are also related.

Crash Group 1

[UIWebBrowserView _collectAdditionalSubviews]
objc_msgSend() selector name: autorelease

Crash Group 2

[UIWebDocumentView subviews]
objc_msgSend() selector name: arrayByAddingObjectsFromArray:

解决方案

I am answering to my own question, since I am able to replicate this issue and found the root cause.

Please not the following.

1. I am using a UIWebView. First of all, this is not recommended.

2. The following way of implementation causes this issue. I am writing a pseudo-code here to demonstrate the problem.

@implementation MyViewController

    - (void)loadView {

        //creating UIWebView Here
        self.webView = [[UIWebView alloc] initWithFrame:_some_frame];

        //setting the web view properties here.

        //Adding to the view
        [self.view addSubView: self.webView];

        [self populateWebView];
    }

    - (void) populateWebView {
        [self.webView loadHTMLString:_some_html 
                             baseURL:[NSURL fileURLWithPath:_some_path]];
    }


    - (void)viewDidLayoutSubviews {
        [super viewDidLayoutSubviews];

        if (self.webView) {
           //The following two lines causing this issue.
           self.webView.scrollView.contentInset = _some_insets;
           self.webView.scrollView.scrollIndicatorInsets = _some_insets;
        }
    }

@end

3. The solution is given below.

@implementation MyViewController

    - (void)loadView {

        //creating UIWebView Here
        self.webView = [[UIWebView alloc] initWithFrame:_some_frame];

        //setting the web view properties here.

        //Adding to the view
        [self.view addSubView: self.webView];

        [self populateWebView];
    }

    - (void) populateWebView {
        [self.webView loadHTMLString:_some_html 
                             baseURL:[NSURL fileURLWithPath:_some_path]];
    }


    - (void)viewDidLayoutSubviews {
        [super viewDidLayoutSubviews];
    }

    - (void)webViewDidFinishLoad:(UIWebView *)webView {
        webView.scrollView.contentInset = _some_insets;
        webView.scrollView.scrollIndicatorInsets = _some_insets;
    }

@end

In my actual code, I was using a custom WebView class here by subclassing the UIWebView. Not think that will create some issue. The root cause is setting the "contentInset" and "scrollIndicatorInsets" in viewDidLayoutSubviews which is not a good idea. When I put the break points, "viewDidLayoutSubviews" called several times and eventually App crashes.

As a solution I moved the following part of the code into "webViewDidFinishLoad" and which will call only when the WebView is ready after finished loading. So making sense to add these codes under this delegate method.

webView.scrollView.contentInset = _some_insets;
webView.scrollView.scrollIndicatorInsets = _some_insets;

这篇关于UIWebDocumentView _updateSubviewCaches在iOS10中崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆