UIWebDocumentView _updateSubviewCache сбой в iOS10

В iOS10 я более серьезно отношусь к сбою в HockeyApp. Пожалуйста, найдите журнал сбоев, как показано ниже.

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

Любая идея, что здесь происходит? Похоже, что также связаны следующие группы сбоев.

Crash Group 1

[UIWebBrowserView _collectAdditionalSubviews]
objc_msgSend() selector name: autorelease

Crash Group 2

[UIWebDocumentView subviews]
objc_msgSend() selector name: arrayByAddingObjectsFromArray:
+4
источник поделиться
1 ответ

Я отвечаю на свой вопрос, так как я могу воспроизвести эту проблему и нашел основную причину.

Обратите внимание на следующее.

1. Я использую UIWebView. Прежде всего, это не рекомендуется.

2. Следующий способ реализации вызывает эту проблему. Здесь я пишу псевдокод, чтобы продемонстрировать проблему.

@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. Решение приведено ниже.

@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

В моем фактическом коде я использовал пользовательский класс WebView, подклассифицировав UIWebView. Не думаю, что это создаст проблему. Коренной причиной является установка contentInset "и" scrollIndicatorInsets viewDidLayoutSubviews, что не очень хорошая идея. Когда я помещал точки останова," viewDidLayoutSubviews" вызывался несколько раз и, в конечном итоге, сбой приложений.

В качестве решения я переместил следующую часть кода в " webViewDidFinishLoad", который вызывается только тогда, когда WebView готов после завершения загрузки. Поэтому имеет смысл добавить этот код в этот метод делегата.

webView.scrollView.contentInset = _some_insets;
webView.scrollView.scrollIndicatorInsets = _some_insets;
+1
источник

Посмотрите другие вопросы по меткам или Задайте вопрос