You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WKWebview键盘输入偶发死锁求助(iOS17情况加剧)

WKWebView键盘输入偶发死锁(iOS17恶化)排查与解决方案

调用栈分析

从提供的调用栈来看,死锁核心出现在键盘自动纠错逻辑的跨线程同步等待环节:

  • 主线程卡在-[UIKeyboardTaskQueue lockWhenReadyForMainThread]等待条件锁释放,而该锁的持有或任务队列调度出现阻塞。
  • 整个触发链路是:UIWKTextInteractionAssistant发起自动纠错请求,通过IPC向WebKit进程获取WebAutocorrectionData,回调回到主线程时触发键盘任务队列的锁等待,最终导致死锁。
  • iOS17后问题恶化,大概率是苹果调整了该版本中键盘自动纠错的线程调度或IPC交互逻辑,加剧了线程竞争冲突。

已尝试方案失效原因

仅设置网页input的autocorrect=off,只能禁用网页层面的自动纠错,但WKWebView内置的UIWKTextInteractionAssistant仍会触发系统级文本替换、拼写检查等逻辑,无法彻底阻断死锁的触发链路。

可行解决方案

1. 配置层面彻底禁用WebKit文本辅助功能

直接在WKWebView配置中关闭拼写检查、自动纠错及文本替换,从根源切断触发逻辑:

WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
// 禁用拼写检查
if (@available(iOS 10.0, *)) {
    config.defaultWebPreferences.spellCheckingEnabled = NO;
}
// 禁用自动纠错与文本替换
config.defaultWebPreferences.autocorrectionEnabled = NO;
config.defaultWebPreferences.automaticTextReplacementEnabled = NO;
// 初始化WebView
WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:config];

该方案比网页端设置更彻底,直接从WebKit内核层面禁用相关功能,无审核风险。

2. Runtime拦截自动纠错弹窗触发逻辑

通过方法交换拦截UIWKTextInteractionAssistant的纠错弹窗触发方法,阻断死锁链路:

#import <objc/runtime.h>

@implementation UIWKTextInteractionAssistant (DeadLockFix)
+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        SEL originalSel = @selector(showReplacementsForText:withOptions:rects:);
        SEL swizzledSel = @selector(fix_showReplacementsForText:withOptions:rects:);
        
        Method originalMethod = class_getInstanceMethod(self, originalSel);
        Method swizzledMethod = class_getInstanceMethod(self, swizzledSel);
        
        BOOL didAdd = class_addMethod(self, originalSel, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
        if (didAdd) {
            class_replaceMethod(self, swizzledSel, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}

- (void)fix_showReplacementsForText:(NSString *)text withOptions:(NSDictionary *)options rects:(NSArray *)rects {
    // 空实现,阻断纠错弹窗及后续逻辑
}
@end

注意:使用Runtime方法交换需注意苹果审核风险,建议通过开关控制仅在死锁场景启用。

3. 等待官方修复+提交Bug反馈

  • 持续关注iOS17后续小版本更新,苹果可能在补丁中修复该死锁问题;
  • 整理复现步骤、设备信息、完整调用栈,通过苹果Feedback Assistant提交Bug报告,推动官方修复。

4. 极端场景备选:异步化键盘任务(风险较高)

如果必须保留自动纠错功能,可尝试将键盘任务队列的同步执行改为异步,但可能破坏键盘内部逻辑,仅作为最后备选:

@implementation UIKeyboardTaskQueue (DeadLockFix)
+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Method originalMethod = class_getInstanceMethod(self, @selector(performSingleTask:));
        Method swizzledMethod = class_getInstanceMethod(self, @selector(fix_performSingleTask:));
        method_exchangeImplementations(originalMethod, swizzledMethod);
    });
}

- (void)fix_performSingleTask:(void (^)(void))task {
    dispatch_async(dispatch_get_main_queue(), task);
}
@end

总结

优先尝试方案1(配置层面禁用文本辅助功能),若无效再考虑方案2的Runtime拦截。方案4风险较高,仅在极端场景下使用。同时建议提交官方Bug反馈,等待系统层面的彻底修复。

内容的提问来源于stack exchange,提问作者Luhui

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 08:10:59