美文网首页适配
解决iOS14Emoji表情Search崩溃

解决iOS14Emoji表情Search崩溃

作者: iOS_zy | 来源:发表于2021-09-27 17:49 被阅读0次
    IMG_53E7687592F7-1.jpeg

    iOS 14 开始,系统的 emoji 键盘内部有一个搜索框 TUIEmojiSearchTextField,这个搜索框如果在 init 的时候设置 delegate(或者设置了keyboardAppearance) 会导致触发死循环,目前我们并不需要为这个新的系统TF做代理,所以需要过滤掉它。

    我出错的位置是BlocksKit里面改用了“TUIEmojiSearchTextField”的delegate。BlocksKit会在把delegate变成block使用,非常方便,但是这里明显是转换了一个我们并不需要的delegate所以在BlocksKit获取delegate的地方过滤它。

    通过断点,我发现会有一个TUIEmojiSearchTextField的delegate在“bk_registerDynamicDelegateNamed:forProtocol:”方法中被调用,它主要功能就是修改 getter 和 setter 方法,将原有的 delegate 转发到 realDelegate,修改原有的 delegate 的实现。下图即是bk_registerDynamicDelegateNamed:forProtocol方法。

    + (void)bk_registerDynamicDelegateNamed:(NSString *)delegateName forProtocol:(Protocol *)protocol
    {
        NSMapTable *propertyMap = [self bk_delegateInfoByProtocol:YES];
        A2BlockDelegateInfo *infoAsPtr = (__bridge void *)[propertyMap objectForKey:protocol];
        if (infoAsPtr != NULL) { return; }
    
        const char *name = delegateName.UTF8String;
        objc_property_t property = class_getProperty(self, name);
        SEL setter = setterForProperty(property, name);
        SEL a2_setter = prefixedSelector(setter);
        SEL getter = getterForProperty(property, name);
    
        A2BlockDelegateInfo info = {
            setter, a2_setter, getter
        };
    
        [propertyMap setObject:(__bridge id)&info forKey:protocol];
        infoAsPtr = (__bridge void *)[propertyMap objectForKey:protocol];
    
        IMP setterImplementation = imp_implementationWithBlock(^(NSObject *delegatingObject, id delegate) {
            A2DynamicDelegate *dynamicDelegate = getDynamicDelegate(delegatingObject, protocol, infoAsPtr, YES);
            if ([delegate isEqual:dynamicDelegate]) {
                delegate = nil;
            }
            dynamicDelegate.realDelegate = delegate;
        });
    
        if (!swizzleWithIMP(self, setter, a2_setter, setterImplementation, "v@:@", YES)) {
            bzero(infoAsPtr, sizeof(A2BlockDelegateInfo));
            return;
        }
    
        if (![self instancesRespondToSelector:getter]) {
            IMP getterImplementation = imp_implementationWithBlock(^(NSObject *delegatingObject) {
                return [delegatingObject bk_dynamicDelegateForProtocol:a2_protocolForDelegatingObject(delegatingObject, protocol)];
            });
    
            addMethodWithIMP(self, getter, NULL, getterImplementation, "@@:", NO);
        }
    }
    

    在imp_implementationWithBlock中,加入判断代码:

    if(@available(iOS 13.0, *)) {
              if([delegate isKindOfClass:NSClassFromString(@"TUIEmojiSearchTextField")]) {
                  delegate = nil;
              }
            }
    

    代码位置如下:


    WX20210927-174752@2x.png

    文章方法参考自腾讯的QMUI的1042问题:Tencent/QMUI_iOS/issues/1042

    相关文章

      网友评论

        本文标题:解决iOS14Emoji表情Search崩溃

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