最近线上不定期上报了四次同样的闪退问题,开始引起我的注意,四次问题都是在iOS13.0以上系统,threading violation: expected the main thread
,应该是多线程问题,应该是13以上的系统更加注重主线程安全问题吧。
附上闪退的有价值输出日志:
CoreFoundation +[_CFXNotificationTokenRegistration keyCallbacks]
Foundation -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 128
UIKitCore -[FBSScene(UIApp) updateUIClientSettingsWithBlock:] + 168
UIKitCore -[UIDevice(Private) _enableDeviceOrientationEvents:] + 140
UIKitCore -[UIDevice endGeneratingDeviceOrientationNotifications] + 56
通过四次的问题页面追踪来分析,可以确定是跟拍照脱不了干系,自己手动测试后可以重现一个问题:
打开拍照->打开闪光灯->拍照的时候立马按下home键。此后在回到页面,发现照片是黑色的,然后我点击取消,发现图片为nil,并且enableDeviceOrientationEvents是在子线程中。
解决方法:
static inline void bd_swizzleSelector(Class theClass, SEL originalSelector, SEL swizzledSelector) {
Method originalMethod = class_getInstanceMethod(theClass, originalSelector);
Method swizzledMethod = class_getInstanceMethod(theClass, swizzledSelector);
method_exchangeImplementations(originalMethod, swizzledMethod);
}
+ (void)load {
///这个10.0看自己的想法
if ([UIDevice currentDevice].systemVersion.floatValue >= 10.0) {
bd_swizzleSelector(UIDevice.class, @selector(endGeneratingDeviceOrientationNotifications), @selector(bdEndGeneratingDeviceOrientationNotifications));
}
}
- (void)bdEndGeneratingDeviceOrientationNotifications
{
if (![NSThread isMainThread]) {
///线上闪退的应该是在这个地方
dispatch_async(dispatch_get_main_queue(), ^{
[self bdEndGeneratingDeviceOrientationNotifications];
});
return;
}
[self bdEndGeneratingDeviceOrientationNotifications];
}
网上也有 通过添加bool属性控制beginGeneratingDeviceOrientationNotifications和endGeneratingDeviceOrientationNotifications成对出现的方案,虽然理论上没什么问题,但是个人认为系统调用的api,咱能不掺合尽量不要掺合,避免出现二次bug。当然最终选择什么方案还是自己说了算。
网友评论