iOS - 如何从崩溃日志中确定导致程序崩溃的原因(在_WebTryThreadLock中)

4
我一直在尝试找出导致我的iOS应用程序崩溃的原因之一。看起来有一些布局发生在后台线程上,这导致它崩溃。有没有办法确定我可能正在触发此重新布局的操作?我从堆栈中推断出,当我的应用程序被带回前台时,与UIWebView相关联。

关于此主题的其他stackoverflow线程似乎提到了一些诸如在后台线程上触发表格重新加载之类的事情。就我所见,所有webView委托方法都在主线程上调用。是否存在某些情况不是这样或者还有其他在后台线程上调用的方法,而我只是不知道?

Web Thread - Crashed.

0    WebCore _WebTryThreadLock(bool) + 297
1    WebCore _WebTryThreadLock(bool) + 288
2    WebCore WebThreadLock + 66
3    UIKit -[UIWebDocumentView(UIWebDocumentViewTextSelecting) selectionBaseWritingDirection] + 10
4    UIKit -[UITextField _currentTextAlignment] + 86
5    UIKit -[UITextField _showsClearButtonWhenNonEmpty:] + 58
6    UIKit -[UITextField _textRectForBounds:forEditing:] + 678
7    UIKit -[UITextField editingRectForBounds:] + 52
8    UIKit -[UITextField editRect] + 70
9    UIKit -[UITextField layoutSubviews] + 1320
10   UIKit -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 258
11   QuartzCore -[CALayer layoutSublayers] + 214
12   QuartzCore CA::Layer::layout_if_needed(CA::Transaction*) + 460
13   QuartzCore CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 16
14   QuartzCore CA::Context::commit_transaction(CA::Transaction*) + 238
15   QuartzCore CA::Transaction::commit() + 316
16   QuartzCore CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 60
17   CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 20
18   CoreFoundation __CFRunLoopDoObservers + 276
19   CoreFoundation CFRunLoopRunSpecific + 394
20   CoreFoundation CFRunLoopRunInMode + 104
21   WebCore RunWebThread(void*) + 444
22   libsystem_c.dylib pthread_start + 308

主线程

0    libsystem_kernel.dylib __psynch_mutexwait + 24
1    libsystem_c.dylib pthread_mutex_lock + 392
2    WebCore _WebTryThreadLock(bool) + 336
3    WebCore WebThreadLock + 66
4    WebKit -[WebDatabasePauser applicationWillEnterForeground] + 16
5    CoreFoundation _CFXNotificationPost + 1426
6    Foundation -[NSNotificationCenter postNotificationName:object:userInfo:] + 72
7    UIKit -[UIApplication _sendWillEnterForegroundCallbacks] + 154
8    UIKit -[UIApplication _handleApplicationResumeEvent:] + 1094
9    UIKit -[UIApplication handleEvent:withNewEvent:] + 1292
10   UIKit -[UIApplication sendEvent:] + 72
11   UIKit _UIApplicationHandleEvent + 6154
12   GraphicsServices _PurpleEventCallback + 590
13   CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 14
14   CoreFoundation __CFRunLoopDoSources0 + 212
15   CoreFoundation __CFRunLoopRun + 646
16   CoreFoundation CFRunLoopRunSpecific + 356
17   CoreFoundation CFRunLoopRunInMode + 104
18   GraphicsServices GSEventRunModal + 74
19   UIKit UIApplicationMain + 1120
20   AppName main.m line 23
1个回答

0

看起来你正在后台线程上更新UI,在你的代码中,无论何时你在后台线程上获取数据并更新UI,请添加这行代码:

dispatch_async(dispatch_get_main_queue(), ^{
                    // Update data here
});

一旦您的代码感觉到设备上有数据,并且是时候根据新数据更新UI了,那么请尝试将主线程重新激活。

希望这能帮到您。


1
感谢您抽出时间回复。我的主要问题是我不确定这个后台线程上的更新发生在哪里。据我所知,所有通知都是在主线程上发生的。我已经尝试在与UIWebView相关的每个函数上设置断点和日志记录。是否有一些关于Web视图的常见回调会在后台线程上发生,而我只是错过了它? - Rajusa
你是否拥有这个方法?- (void)webViewDidFinishLoad:(UIWebView *)webView {} 这个方法可以告诉你webview已经加载完成,现在可以将控制权传递给主线程。 - Reno Jones
或者在您的代码中执行此操作并测试其是否正常工作 -// 创建和分配UIWebView对象,我将其称为webViewObj NSURL *webURLObj = [NSURL URLWithString:url];dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);dispatch_async(queue, ^{NSURLRequest *request = [NSURLRequest requestWithURL:webURLObj]; [webViewObj loadRequest:request]; dispatch_sync(dispatch_get_main_queue(), ^{ [webViewObj release]; });}); - Reno Jones
@RenoJones:根据我的测试,webViewDidFinishLoad:和其他UIWebView代理方法总是在主线程上调用。 - user102008

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