iPhone应用在WebThread上崩溃,MPVolumeSlider。

15

问一个问题似乎很广泛,但修复错误非常麻烦和困难。

这是我从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

我在开发过程中从未见过这种崩溃(如果能够使用断点和控制台日志捕获到,我会非常高兴),但它只在用户使用时出现。

只能通过Crashlytics报告。

可能的原因:

应用程序使用MagicalRecord并在启动时从服务器获取数据,使用多线程,当WebKit正在使用UIKit部分和锁定时,另一个主线程似乎访问它。 所以我尝试删除所有dispatch_sync并将其更改为dispatch_async,但在进行几个功能调用后崩溃再次发生。

我想知道的是,为什么WebCore正在运行,而我从未请求在UIWebView上使用MPVolumeController。

即使它们可以因为某些原因在后台运行,为什么会崩溃? 它经常发生,用户抱怨。

其他人有同样的问题吗?


一样的问题... 这是我最常见的崩溃,它开始出现在 iOS 8 中。我花了几天时间寻找解决方案,但无济于事... - cujo30227
既然如此,就在苹果的开发者论坛或其他地方看不到任何东西。 - bpapa
想知道是否将UIWebView更换为WKWebView会有帮助,但是还没有尝试过。 - bpapa
1
也许可以,但是没有必要打开MPVolumeView。 - vichevstefan
1个回答

2

这个bug从iOS 8开始出现。

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

我是这样修复它的:

@interface H5WebKitBugsManager : NSObject

+ (void)fixAllBugs;

@end


#import "H5WebKitBugsManager.h"
#import <objc/runtime.h>

void H5Swizzle(Class c, SEL orig, SEL new)
{
    Method origMethod = class_getInstanceMethod(c, orig);
    Method newMethod = class_getInstanceMethod(c, new);
    if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) {
        class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
    } else {
        method_exchangeImplementations(origMethod, newMethod);
    }
}

@implementation H5WebKitBugsManager

+ (void)fixAllBugs
{
    [self fixBug_MediaPlayerVolumeView];
}

+ (void)fixBug_MediaPlayerVolumeView
{
    CGFloat systemVersion = [UIDevice currentDevice].systemVersion.floatValue;

    if (systemVersion < 8.0f || systemVersion > 9.1) {
    // below ios version 8.0 has no VolumeView
        return;
    }

    Class cls = NSClassFromString(@"WebMediaSessionHelper");
    NSString *allocateVolumeView = @"allocateVolumeView";
    SEL orig = NSSelectorFromString(allocateVolumeView);
    SEL new = @selector(H5WKBMAllocateVolumeView);
    Method newMethod = class_getInstanceMethod(self, new);

    if(class_addMethod(cls, new, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) {
        H5Swizzle(cls, orig, new);
    }
}

- (void)H5WKBMAllocateVolumeView
{
    // WebKit's MediaSessionManageriOS is a singleton,in MediaSessionManageriOS.m. svn version181,859.
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
            // must be dispatch in background thread
            [self H5WKBMAllocateVolumeView];
        });
    });
}

@end

似乎在后台线程中使用MPVolumeViewallocinit引起了问题。allocateVolumeView已经在WebThread(后台线程)中了。 - ooops

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