iPhone应用程序在WebThread MPVolumeSlider上崩溃

vic*_*fan 15 iphone objective-c uiwebview ios

问一个问题似乎非常宽泛,但这很烦人且难以修复bug.

这是我从Crashlytics获得的WebThread崩溃日志.

Thread : Crashed: WebThread
0  libobjc.A.dylib                0x0000000193e97bd0 objc_msgSend + 16
1  UIKit                          0x0000000187f65dd8 +[UIViewAnimationState  popAnimationState] + 332
2  MediaPlayer                    0x0000000185953358 -[MPVolumeSlider volumeController:volumeValueDidChange:] + 92
3  MediaPlayer                    0x00000001859c5fc4 -[MPVolumeController updateVolumeValue] + 260
4  MediaPlayer                    0x0000000185952cb0 -[MPVolumeSlider didMoveToSuperview] + 144
5  UIKit                          0x0000000187f2c1dc -[UIView(Hierarchy) _postMovedFromSuperview:] + 484
6  UIKit                          0x0000000187f37cbc -[UIView(Internal) _addSubview:positioned:relativeTo:] + 1764
7  MediaPlayer                    0x0000000185955f54 -[MPVolumeView _createSubviews] + 264
8  MediaPlayer                    0x00000001859549d4 -[MPVolumeView _initWithStyle:] + 240
9  MediaPlayer                    0x0000000185954a60 -[MPVolumeView initWithFrame:style:] + 88
10 WebCore                        0x0000000191ba4684 -[WebMediaSessionHelper initWithCallback:] + 132
11 WebCore                        0x0000000191ba3db8 WebCore::MediaSessionManageriOS::MediaSessionManageriOS() + 96
12 WebCore                        0x0000000191ba3d28 WebCore::MediaSessionManager::sharedManager() + 56
13 WebCore                        0x0000000191ba2890 WebCore::MediaSession::MediaSession(WebCore::MediaSessionClient&) + 44
14 WebCore                        0x00000001916e8604 WebCore::HTMLMediaSession::create(WebCore::MediaSessionClient&) + 36
15 WebCore                        0x00000001916d0fb0 WebCore::HTMLMediaElement::HTMLMediaElement(WebCore::QualifiedName const&, WebCore::Document&, bool) + 1100
16 WebCore                        0x000000019170a2b4 WebCore::HTMLVideoElement::create(WebCore::QualifiedName const&, WebCore::Document&, bool) + 68
17 WebCore                        0x00000001916bdd9c WebCore::videoConstructor(WebCore::QualifiedName const&, WebCore::Document&, WebCore::HTMLFormElement*, bool) + 92
Run Code Online (Sandbox Code Playgroud)

我在开发过程中从未见过这种崩溃(当我可以通过断点和控制台日志捕获它时,我会非常高兴),但只有在用户处于实时状态时才会显示.

只能由crashlytics报告.

可能的原因;

应用程序使用MagicalRecord并在启动时从后台获取服务器中的数据.这使用多线程,当webkit使用UIKit部分和锁定时,另一个主线程似乎访问它.所以我试图删除所有dispatch_sync并将其更改为dispatch_async,但在进行一些函数调用后再次发生崩溃.

我想知道的是,为什么WebCore正在运行,我从未在UIWebView上请求过MPVolumeController.

即使他们可以出于某种原因在背景上运行,为什么它会崩溃?它经常发生并且用户投诉.

其他人有同样的问题吗?

小智 2

这个bug从iOS 8开始就出现了。

\n\n

加载包含audiovideo元素的 HTML 的 UIWebView 会随机崩溃。

\n\n

我是这样修复的:

\n\n
@interface H5WebKitBugsManager : NSObject\n\n+ (void)fixAllBugs;\n\n@end\n\n\n#import "H5WebKitBugsManager.h"\n#import <objc/runtime.h>\n\nvoid H5Swizzle(Class c, SEL orig, SEL new)\n{\n    Method origMethod = class_getInstanceMethod(c, orig);\n    Method newMethod = class_getInstanceMethod(c, new);\n    if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) {\n        class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));\n    } else {\n        method_exchangeImplementations(origMethod, newMethod);\n    }\n}\n\n@implementation H5WebKitBugsManager\n\n+ (void)fixAllBugs\n{\n    [self fixBug_MediaPlayerVolumeView];\n}\n\n+ (void)fixBug_MediaPlayerVolumeView\n{\n    CGFloat systemVersion = [UIDevice currentDevice].systemVersion.floatValue;\n\n    if (systemVersion < 8.0f || systemVersion > 9.1) {\n    // below ios version 8.0 has no VolumeView\n        return;\n    }\n\n    Class cls = NSClassFromString(@"WebMediaSessionHelper");\n    NSString *allocateVolumeView = @"allocateVolumeView";\n    SEL orig = NSSelectorFromString(allocateVolumeView);\n    SEL new = @selector(H5WKBMAllocateVolumeView);\n    Method newMethod = class_getInstanceMethod(self, new);\n\n    if(class_addMethod(cls, new, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) {\n        H5Swizzle(cls, orig, new);\n    }\n}\n\n- (void)H5WKBMAllocateVolumeView\n{\n    // WebKit\'s MediaSessionManageriOS is a singleton\xef\xbc\x8cin MediaSessionManageriOS.m. svn version181,859.\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ \n            // must be dispatch in background thread\n            [self H5WKBMAllocateVolumeView];\n        });\n    });\n}\n\n@end\n
Run Code Online (Sandbox Code Playgroud)\n