美文网首页
iOS13下调用相机crash分析及解决

iOS13下调用相机crash分析及解决

作者: 节奏不对啊 | 来源:发表于2019-12-24 17:55 被阅读0次

    在iOS13中,系统对在子线程进行UI操作做了更加严格的检验,会直接抛出 threading violation: expected the main thread 。该问题在真实项目中,我们对堆栈信息中的 [UIDevice endGeneratingDeviceOrientationNotifications] 进行 hook 处理,通过 Crash必现的路径,看到这个方法会发生在子线程中:

    @implementation UIDevice (PG)

    static inline void pg_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 {

        if ([UIDevice currentDevice].systemVersion.floatValue >= 13.0) {

            pg_swizzleSelector(UIDevice.class, @selector(endGeneratingDeviceOrientationNotifications), @selector(pgEndGeneratingDeviceOrientationNotifications));

        }

    }

    - (void)pgEndGeneratingDeviceOrientationNotifications {

        NSLog(@"pgEndGeneratingDeviceOrientationNotifications isMainThread:%d", [NSThread isMainThread]);

        [self pgEndGeneratingDeviceOrientationNotifications];

    }

    @end

    hook  [UIDevice endGeneratingDeviceOrientationNotifications] 判断执行该方法是否在主线程中执行,如果不是,则同步到主线程中转发: (最终代码)

    @implementation UIDevice (PG)

    static inline void pg_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 {

        if ([UIDevice currentDevice].systemVersion.floatValue >= 13.0) {

            pg_swizzleSelector(UIDevice.class, @selector(endGeneratingDeviceOrientationNotifications), @selector(pgEndGeneratingDeviceOrientationNotifications));

        }

    }

    - (void)pgEndGeneratingDeviceOrientationNotifications {

        NSLog(@"pgEndGeneratingDeviceOrientationNotifications isMainThread:%d", [NSThread isMainThread]);

        [self pgEndGeneratingDeviceOrientationNotifications];

    }

    @end

    问题结束了?

    上面的问题解决,其实的确是能解决问题,但是并没有从根源上发现到底是什么地方导致,通过查看代码发现,我们的项目中对 [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications] 、[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications] 没有成对实现,测试发现,如果 多调用了两次 [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications] , 然后再唤起H5的拍照/录视频,在iOS13系统上必然Crash,可以在下载 HDCameraCrashDemo 进行验证

    可以在 [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications] 、[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications] 添加一个 BOOL 类型的变量来控制他们的成对出现,从根本上解决这类问题。

    所以这个并不一定是iOS13系统的问题,只要在调用系统方法合理,并不会有该类型的Crash发生。

    ————————————————

    原作者戳链接:https://blog.csdn.net/u012390519/article/details/103680390

    相关文章

      网友评论

          本文标题:iOS13下调用相机crash分析及解决

          本文链接:https://www.haomeiwen.com/subject/roqnettx.html