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

WKWebView子类按ESC键触发_cancelOperation:未识别选择器异常

自定义WKWebView子类按下ESC键抛出_cancelOperation:未识别选择器异常的问题与解决

问题描述

在iOS混合WebView应用中,使用自定义WKWebView子类MyBrandWebView时出现异常:当WebView内输入框聚焦时按下ESC键,会抛出以下NSException:

Exception NSException * "-[App.MyBrandWebView _cancelOperation:]: unrecognized selector sent to instance 0x119027400" 0x0000600000cfb9c0

尝试过的无效方案

最初尝试在子类中实现_cancelOperation:和cancelOperation:方法,但无法解决问题,代码如下:

class MyBrandWebView: WKWebView {

  @objc func _cancelOperation(sender: Any?) {
    
  }
  
  
  @objc func cancelOperation(sender: Any?) {
    
  }
}

堆栈跟踪

*** First throw call stack:
(
    0   CoreFoundation                      0x00000001804658a8 __exceptionPreprocess + 172
    1   libobjc.A.dylib                     0x000000018005c09c objc_exception_throw + 56
    2   CoreFoundation                      0x000000018047a6f8 +[NSObject(NSObject) instanceMethodSignatureForSelector:] + 0
    3   UIKitCore                           0x0000000110a7b3d4 -[UIResponder doesNotRecognizeSelector:] + 232
    4   CoreFoundation                      0x00000001804699f8 ___forwarding___ + 1280
    5   CoreFoundation                      0x000000018046bd1c _CF_forwarding_prep_0 + 92
    6   UIKitCore                           0x000000011084fe28 -[UIKeyboardImpl _cancelOperation:testOnly:] + 636
    7   UIKitCore                           0x00000001108512a8 -[UIKeyboardImpl handleKeyCommand:repeatOkay:options:] + 3760
    8   UIKitCore                           0x0000000110880e80 -[UIKeyboardImpl _handleKeyCommandCommon:options:] + 72
    9   UIKitCore                           0x0000000110880e28 -[UIKeyboardImpl _handleKeyCommand:] + 16
    10  UIKitCore                           0x00000001108665b4 -[UIKeyboardImpl handleKeyTextCommandForCurrentEvent] + 236
    11  WebKit                              0x0000000107d8b3bc -[WKContentView(WKInteraction) _interpretKeyEvent:isCharEvent:] + 160
    12  WebKit                              0x000000010789f8c4 _ZN6WebKit14PageClientImpl17interpretKeyEventERKNS_22NativeWebKeyboardEventEb + 48
    13  WebKit                              0x00000001078c4cb0 _ZN6WebKit12WebPageProxy17interpretKeyEventERKNS_11EditorStateEbON3WTF17CompletionHandlerIFvbEEE + 140
    14  WebKit                              0x0000000107cda790 _ZN6WebKit12WebPageProxy21didReceiveSyncMessageERN3IPC10ConnectionERNS1_7DecoderERN3WTF9UniqueRefINS1_7EncoderEEE + 3268
    15  WebKit                              0x0000000107dc260c _ZN3IPC18MessageReceiverMap19dispatchSyncMessageERNS_10ConnectionERNS_7DecoderERN3WTF9UniqueRefINS1_7EncoderEEE + 276
    16  WebKit                              0x00000001079eb928 _ZN6WebKit15WebProcessProxy21didReceiveSyncMessageERN3IPC10ConnectionERNS1_7DecoderERN3WTF9UniqueRefINS1_7EncoderEEE + 40
    17  WebKit                              0x0000000107dbe6f0 _ZN3IPC10Connection15dispatchMessageENSt3__110unique_ptrINS_7DecoderENS1_14default_deleteIS3_EEEE + 728
    18  WebKit                              0x0000000107dbff58 _ZN3WTF6Detail15CallableWrapperIZN3IPC10Connection16SyncMessageState22processIncomingMessageERS3_RNSt3__110unique_ptrINS2_7DecoderENS6_14default_deleteIS8_EEEEE3$_5vJEE4callEv + 636
    19  JavaScriptCore                      0x000000010d2dc3d4 _ZN3WTF7RunLoop11performWorkEv + 176
    20  JavaScriptCore                      0x000000010d2dd0e4 _ZN3WTF7RunLoop11performWorkEPv + 32
    21  CoreFoundation                      0x00000001803c669c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
    22  CoreFoundation                      0x00000001803c65e4 __CFRunLoopDoSource0 + 172
    23  CoreFoundation                      0x00000001803c5d54 __CFRunLoopDoSources0 + 232
    24  CoreFoundation                      0x00000001803c043c __CFRunLoopRun + 768
    25  CoreFoundation                      0x00000001803bfd28 CFRunLoopRunSpecific + 572
    26  GraphicsServices                    0x000000018986ebc0 GSEventRunModal + 160
    27  UIKitCore                           0x0000000110a4ffdc -[UIApplication _run] + 868
    28  UIKitCore                           0x0000000110a53c54 UIApplicationMain + 124
    29  App                                 0x00000001001fc684 main + 64
    30  dyld                                0x00000001003d1558 start_sim + 20
    31  ???                                 0x00000001004b6058 0x0 + 4299907160
    32  ???                                 0x8343000000000000 0x0 + 9458403642408173568
)
libc++abi: terminating due to uncaught exception of type NSException

原因分析

从堆栈跟踪可见,ESC键触发的事件经UIKit、WebKit处理后,通过响应链传递到MyBrandWebView,系统尝试调用私有方法_cancelOperation:时,子类的Swift实现无法匹配Objective-C的方法签名——Swift中声明的sender: Any?会自动添加参数标签,生成的选择器是_cancelOperationWithSender:,而非系统期望的_cancelOperation:。此外,WKWebView的私有实现依赖响应链传递该消息,直接在子类添加方法无法覆盖系统的调用逻辑。

解决方案

方案1:Objective-C分类添加方法

通过Objective-C分类为WKWebView添加匹配签名的_cancelOperation:方法,该分类会作用于所有WKWebView及其子类:

// WKWebView+CancelOperation.h
#import <WebKit/WebKit.h>

@interface WKWebView (CancelOperation)
@end

// WKWebView+CancelOperation.m
#import "WKWebView+CancelOperation.h"

@implementation WKWebView (CancelOperation)

- (void)_cancelOperation:(id)sender {
    // 空实现即可避免异常
}

@end

方案2:Swift子类重写消息转发方法

在MyBrandWebView中重写消息转发相关方法,拦截未识别的_cancelOperation:选择器:

class MyBrandWebView: WKWebView {
    override func forwardInvocation(_ invocation: NSInvocation) {
        let selector = invocation.selector
        if selector == #selector(_cancelOperation(_:)) {
            // 忽略该调用
            return
        }
        super.forwardInvocation(invocation)
    }

    override func methodSignature(for selector: Selector!) -> NSMethodSignature! {
        if selector == #selector(_cancelOperation(_:)) {
            // 匹配系统期望的方法签名:返回值void,参数为id
            return NSMethodSignature.signature(withObjCTypes: "v@:@")
        }
        return super.methodSignature(for: selector)
    }

    @objc private func _cancelOperation(_ sender: Any?) {
        // 空实现
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 04:03:10