UIResponder didNotRecognizeSelector

问题描述 投票:2回答:1

由于以下回溯,我经常崩溃,但找不到原因。

根据Apple -[-[NSObject(NSObject)didNotRecognizeSelector:]]在先前由已释放对象占用的内存中分配了新对象时发生。

注意:

向先前释放的对象发送消息可能会引发NSInvalidArgumentException而不是使程序崩溃内存访问冲突。当在其中分配新对象时,会发生这种情况先前由已释放对象占用的内存。如果你的由于未捕获的NSInvalidArgumentException而导致应用程序崩溃(在-中查找-[NSObject(NSObject)didNotRecognizeSelector:]异常回溯),请考虑使用僵尸仪器消除了存储不当的可能性管理是原因。

https://developer.apple.com/library/archive/technotes/tn2151/_index.html

但是其余的回溯是怎么回事,特别是-[UIUndoGestureInteraction didMoveToView:]

事情?
Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note:  EXC_CORPSE_NOTIFY
Triggered by Thread:  0

Last Exception Backtrace:
0   CoreFoundation                  0x1ae45498c __exceptionPreprocess + 220 (NSException.m:199)
1   libobjc.A.dylib                 0x1ae17d0a4 objc_exception_throw + 56 (objc-exception.mm:565)
2   CoreFoundation                  0x1ae35843c -[NSObject(NSObject) doesNotRecognizeSelector:] + 140 (NSObject.m:144)
3   UIKitCore                       0x1b24902a8 -[UIResponder doesNotRecognizeSelector:] + 296 (UIResponder.m:659)
4   CoreFoundation                  0x1ae458e08 ___forwarding___ + 1324 (NSForwarding.m:3325)
5   CoreFoundation                  0x1ae45abec _CF_forwarding_prep_0 + 92
6   UIKitCore                       0x1b2353040 -[UIUndoGestureInteraction didMoveToView:] + 108 (UIUndoGestureInteraction.m:725)
7   UIKitCore                       0x1b28eb3c4 _setInteractionView + 84 (UIView.m:16421)
8   UIKitCore                       0x1b28eb2a0 -[UIView(Dragging) addInteraction:] + 268 (UIView.m:16450)
9   UIKitCore                       0x1b26cd2b8 -[UIEditingOverlayViewController _addInteractions] + 260 (UIEditingOverlayViewController.m:79)
10  UIKitCore                       0x1b1e5b2ec -[UIViewController _setViewAppearState:isAnimating:] + 832 (UIViewController.m:4695)
11  UIKitCore                       0x1b1e5b6fc __52-[UIViewController _setViewAppearState:isAnimating:]_block_invoke + 268 (UIViewController.m:4758)
12  CoreFoundation                  0x1ae42773c __NSARRAY_IS_CALLING_OUT_TO_A_BLOCK__ + 16 (NSArrayHelpers.m:9)
13  CoreFoundation                  0x1ae32b86c -[__NSArrayI enumerateObjectsWithOptions:usingBlock:] + 152 (NSArrayI.m:108)
14  UIKitCore                       0x1b1e5b49c -[UIViewController _setViewAppearState:isAnimating:] + 1264 (UIViewController.m:4736)
15  UIKitCore                       0x1b1e5d530 __64-[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:]_block_invoke + 44 (UIViewController.m:5272)
16  UIKitCore                       0x1b1e5c32c -[UIViewController _executeAfterAppearanceBlock] + 88 (UIViewController.m:5050)
17  UIKitCore                       0x1b246bca4 _runAfterCACommitDeferredBlocks + 584 (UIApplication.m:3027)
18  UIKitCore                       0x1b245b7c0 _cleanUpAfterCAFlushAndRunDeferredBlocks + 232 (UIApplication.m:2986)
19  UIKitCore                       0x1b248b594 _afterCACommitHandler + 76 (UIApplication.m:3048)
20  CoreFoundation                  0x1ae3d1c48 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32 (CFRunLoop.c:1758)
21  CoreFoundation                  0x1ae3ccb34 __CFRunLoopDoObservers + 416 (CFRunLoop.c:1868)
22  CoreFoundation                  0x1ae3cd100 __CFRunLoopRun + 1308 (CFRunLoop.c:2910)
23  CoreFoundation                  0x1ae3cc8bc CFRunLoopRunSpecific + 464 (CFRunLoop.c:3192)
24  GraphicsServices                0x1b8238328 GSEventRunModal + 104 (GSEvent.c:2246)
25  UIKitCore                       0x1b24626d4 UIApplicationMain + 1936 (UIApplication.m:4753)
26  JustConnect                     0x10425ca60 main + 68 (APIInfoUser.swift:7)
27  libdyld.dylib                   0x1ae257460 start + 4

我在以下回溯中崩溃很多,但找不到原因。根据苹果公司的说法,当在...中分配新对象时,会发生[NSObject(NSObject)didNotRecognizeSelector:]。

这是Apple开发人员和技术支持的回复:
这里要注意的关键是第0至第5帧回溯只是与无法识别相关的样板选择器。也就是说,框架6调用了对象的方法,对象无法识别该选择器,因此它进入了Objective-C运行时转发基础结构(第5帧到第4帧)。那降落了在UIResponder中(第3帧),因为UIResponder支持某种通用消息转发。该消息转发失败,因此UIResponder称为超级(第2帧),然后引发异常。

所以真正的问题是,第6帧中发生了什么。要了解更多关于这一点,您可以反汇编代码(-:

(lldb) disas -n '-[UIUndoGestureInteraction didMoveToView:]' UIKitCore`-[UIUndoGestureInteraction didMoveToView:]: 0x1bbe92fd4 <+0>: stp x22, x21, [sp, #-0x30]! 0x1bbe92fd8 <+4>: stp x20, x19, [sp, #0x10] 0x1bbe92fdc <+8>: stp x29, x30, [sp, #0x20] 0x1bbe92fe0 <+12>: add x29, sp, #0x20 ; =0x20 0x1bbe92fe4 <+16>: mov x21, x2 0x1bbe92fe8 <+20>: mov x19, x0 0x1bbe92fec <+24>: add x20, x0, #0x10 ; =0x10 0x1bbe92ff0 <+28>: mov x0, x20 0x1bbe92ff4 <+32>: mov x1, x2 0x1bbe92ff8 <+36>: bl 0x1b7cd71d8 ; objc_storeWeak 0x1bbe92ffc <+40>: cbz x21, 0x1bbe930a8 ; <+212> 0x1bbe93000 <+44>: adrp x8, 208464 0x1bbe93004 <+48>: add x1, x8, #0x7b1 ; =0x7b1 0x1bbe93008 <+52>: mov x0, x19 0x1bbe9300c <+56>: bl 0x1b7cb9180 ; objc_msgSend 0x1bbe93010 <+60>: mov x0, x20 0x1bbe93014 <+64>: bl 0x1b7cd7a80 ; objc_loadWeakRetained 0x1bbe93018 <+68>: mov x20, x0 0x1bbe9301c <+72>: adrp x8, 208304 0x1bbe93020 <+76>: add x1, x8, #0xc04 ; =0xc04 0x1bbe93024 <+80>: bl 0x1b7cb9180 ; objc_msgSend 0x1bbe93028 <+84>: mov x29, x29 0x1bbe9302c <+88>: bl 0x1b7cd8864 ; objc_retainAutoreleasedReturnValue 0x1bbe93030 <+92>: mov x21, x0 0x1bbe93034 <+96>: adrp x8, 208502 0x1bbe93038 <+100>: add x1, x8, #0xbb7 ; =0xbb7 0x1bbe9303c <+104>: bl 0x1b7cb9180 ; objc_msgSend 0x1bbe93040 <+108>: stp d0, d1, [x19, #0x100]

您可以在这里学到很多东西。首先,在backtrace的偏移量为+108,因此失败的实际调用位于+104。 objc_msgSend具有两个标准参数,即目标对象和选择器。在64位Arm上,它们分别映射到x0和x1。

让我们先看一下选择器。这是由两个说明在+96和+100。这两条指令构成了PC相对地址。 adrp指令(“相对于页面添加”)取当前PC(0x1bbe93034),清除低12位(0x1bbe93000,请记住历史页面大小为4096 [1]),并且然后获取文字,将其左移12位(208502 << 12),然后然后将其添加。add指令要简单得多。它需要之前计算得出的结果,然后加上0xbb7(请注意开关从十进制到十六进制!)。

如果您在调试器中运行此计算,则会看到以下内容:

(lldb) p (char*)( 0x1bbe93000+(208502<<12)+0xbb7) (char *) $1 = 0x00000001eed09bb7 "actualSceneBounds"

所以选择器是ActualSceneBounds。酷。

现在让我们看一下对象。在通话时(+104),这是预期在x0中。在+92,我们看到它将x0复制到x21,但这是只是分心。实际上x0是从objc_retainAutoreleasedReturnValue为+88。该函数需要和返回一个对象,因此x0是在以下位置发送的消息所返回的值+80。进行与之前相同的相对页面技巧,我们看到该调用的选择器是-window。但是那个对象是什么拜访吗?

解决这个问题……很好……由于objc_storeWeak有点复杂/ objc_loadWeak保留舞蹈。我相信它可以归结为价值通过x2(即第三个参数)传递给此方法。基于在方法名称上,这显然是一个视图(请记住,对于Objective-C方法的前两个参数x0和x1包含目标和选择器,因此x2包含第一个实际参数)。

因此,总而言之:

似乎此方法具有视图参数。

  • 它是请求的window.window.screenBounds。

  • 上一次属性访问失败,因为原本打算作为窗口的东西没有实现-screenBounds吸气剂。
  • 我对UIKit的了解不足,无法解释其背景。一世这里有一些建议:

  • 运行标准内存调试工具,特别是Zombies,以查看它们是否有用。确保锻炼撤消手势,基于我们分开的方法的类名。

  1. 如果没有成功,请跳至App Frameworks> Cocoa Touch,以查看那里是否有任何建议。
  2. 分享和享受

  3. [1]在64位Arm上,实际页面大小通常为64 KiB,但是adrp指令使用历史页面大小4096,因为它匹配添加指令中的最大文字大小。

https://forums.developer.apple.com/message/389467

ios swift crash backtrace
1个回答
1
投票
这里要注意的关键是第0至第5帧回溯只是与无法识别相关的样板选择器。也就是说,框架6调用了对象的方法,对象无法识别该选择器,因此它进入了Objective-C运行时转发基础结构(第5帧到第4帧)。那降落了在UIResponder中(第3帧),因为UIResponder支持某种通用消息转发。该消息转发失败,因此UIResponder称为超级(第2帧),然后引发异常。

所以真正的问题是,第6帧中发生了什么。要了解更多关于这一点,您可以反汇编代码(-:

© www.soinside.com 2019 - 2024. All rights reserved.