处理出现此异常的问题:
异常 NSException *“-[App.MyBrandWebView _cancelOperation:]:无法识别的选择器发送到实例 0x119027400”0x0000600000cfb9c0
每当在 WkWebView 中的输入中键入“ESC”键时抛出该错误。对于上下文,这是一个基于混合 Web 视图的应用程序,我们正在使用自定义 WKWebView 超类。
最初,我认为这个问题是微不足道的,可以通过在
_cancelOperation
子类上定义这个 MyBrandWebView
函数来解决,但这似乎没有效果:
class MyBrandWebView: WKWebView {
@objc func _cancelOperation(sender: Any?) {
}
@objc func cancelOperation(sender: Any?) {
}
}
我正在查看
WKWebView
的继承链,我很难弄清楚这个 cancelOperation
是在哪里定义的,或者更重要的是,为什么它是用转义键触发的。
这是相关的堆栈跟踪
*** 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_7DecoderERN3WTF9UniqueRefINS_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
可以通过在子类上定义运行时选择器来使其工作,如下所示:
let block: @convention(block) (AnyObject?) -> Void = { (self: AnyObject!) -> Void in }
let imp = imp_implementationWithBlock(unsafeBitCast(block, to: AnyObject.self))
class_addMethod(MyBrandWebView.self, NSSelectorFromString("_cancelOperation:"), imp, "i@:@")
不认为这是正确的解决方案,但它确实有效。那我就分享一下吧。