Tencent / QMUI_iOS

QMUI iOS——致力于提高项目 UI 开发效率的解决方案
http://qmuiteam.com/ios
Other
7.08k stars 1.38k forks source link

UISearchBar(QMUI).qmui_alwaysEnableCancelButton 可能出现 crash #1232

Closed MoLice closed 3 years ago

MoLice commented 3 years ago

问题描述

QMUI 4.2.3 里 UISearchBar(QMUI) 新增了属性 qmui_alwaysEnableCancelButton,该属性 hook 了 UINavigationButtonsetEnabled: 方法,在里面试图获取 UISearchBar 的引用然后处理一些逻辑。但在 iOS 里,不仅是搜索框的取消按钮是 UINavigationButton 类型,在 iOS 10 的 UIToolbar 里也存在 UINavigationButton,而 QMUI 的逻辑里没有判断获取到的 searchBar 是否真的是 UISearchBar,导致会对非 UISearchBar 调用不存在的方法,从而引发 crash。

其他信息

lilin87788 commented 3 years ago

请问如何解决

MoLice commented 3 years ago

@lilin87788 将以下代码替换你本地的 UISearchBar+QMUI.m 里的相关代码。

OverrideImplementation(NSClassFromString(@"UINavigationButton"), @selector(setEnabled:), ^id(__unsafe_unretained Class originClass, SEL originCMD, IMP (^originalIMPProvider)(void)) {
    return ^(UIButton *selfObject, BOOL firstArgv) {

        UISearchBar *searchBar = nil;
        if (@available(iOS 13.0, *)) {
            searchBar = (UISearchBar *)selfObject.superview.superview.superview;
        } else {
            searchBar = (UISearchBar *)selfObject.superview.superview;
        }

        if ([searchBar isKindOfClass:UISearchBar.class] && searchBar.qmui_alwaysEnableCancelButton && !searchBar.qmui_searchController) {
            firstArgv = YES;
        }

        // call super
        void (*originSelectorIMP)(id, SEL, BOOL);
        originSelectorIMP = (void (*)(id, SEL, BOOL))originalIMPProvider();
        originSelectorIMP(selfObject, originCMD, firstArgv);
    };
});
lilin87788 commented 3 years ago

您好:我使用pod 集成的如何修改啊

lilin87788 commented 3 years ago

image 现在我这边出现了大量的这个错误导致的闪退

lilin87788 commented 3 years ago

您好:希望判断ios10的版本提交一个新的tag4.2.4 来解决这个问题,非常感谢

MoLice commented 3 years ago

您好:我使用pod 集成的如何修改啊

本地修改就行?多人协作的话建议你们自己 fork 一个 repo,在里面改,然后 Podfile 先把 QMUI 指定到你们的 repo 里

lilin87788 commented 3 years ago

用fork的办法已经解决 谢谢

pagesvr commented 3 years ago

是的,这个BUG我在iOS10的版本上也遇到了,我也是这样改的

MoShenGuo commented 3 years ago

你好 这个hook是干嘛的 你这是hook UISearchBar中UINavigationButton对象setEnabled:方法吧?如果我没有对setEnabled方法调用也会被影响吗?或者没有调用UISearchBar 中UINavigationButton对象方法setEnabled 道理是不会走到你的hook方法的 不知道我理解对不

MoLice commented 3 years ago

你好 这个hook是干嘛的 你这是hook UISearchBar中UINavigationButton对象setEnabled:方法吧?如果我没有对setEnabled方法调用也会被影响吗?或者没有调用UISearchBar 中UINavigationButton对象方法setEnabled 道理是不会走到你的hook方法的 不知道我理解对不

@MoShenGuo 系统也会调用的,不一定是你的业务代码主动触发。

MoLice commented 3 years ago

已发布 4.3.0 修复该问题。