在我们遇到的问题中,事件无法响应算是常客了。有时候甚至花费数小时排查这种问题,其效率低得让人发指。后来决定沉下心来,专心研究一种科学的办法,帮助我们可以快速定位问题。
理解
要想深入了解其原理,非常推荐这篇文章。这里我就不做过多解释。
我们只需要知道事件是由 UIApplication
调用其 sendEvent
方法把事件传递给 keyWindow
,keyWindow
调用其 sendEvent
方法把事件传递给响应的视图。
- (void)sendEvent:(UIEvent *)event;
额外的,发现文档里面的属性 keyWindow 将要被 Deprecated,兼容性为 iOS 2.0–13.0。但是并不影响我们,我们只需要用到
UIWindow
类而已。
Debug
根据上面的关键点,我们可以在 Xcode
里面添加 Symbolic Breakpoint
,具体配置见下图:
你可能会问,为什么不用 -[UIApplication sendEvent:]
,但是这样你除了能得到 window
的信息,其它一无所获。至于下面的 po $arg3
的意思是为了打印 event 参数,可以参考如下说明:
$arg3
…$argn
— represents the parameters sent to that function.
继续执行你的事件操作,这个时候控制台会输出如下信息:
<UITouchesEvent: 0x60000355cd80> timestamp: 984803 touches: {(
<UITouch: 0x7f8743c13750> phase: Ended tap count: 1 force: <TestEventTouch.CView: 0x7f8744a14f40; frame = ...
)}
你可以很容易的获取到是类名为 CView
的视图吃了你的事件。
但是
如果类名为 UIView
或者 NSView
怎么办?并不是所有的视图都是自定义视图类,这可要海底捞针了!
这个时候需要借助于 pviews
这个命令,不过先等等,要用这个命令你还需要做一些准备工作。
chisel
chisel 这是一个 Facebook 用 Python 编写的 LLDB 命令集合。按照 Github 上面的步骤安装即可。不过最后如果你的目录 /usr/local/opt/chisel/libexec
里面如果没有 fbchisellldb.py
的话,可以用 fblldb.py
代替。话说这是不是 Facebook 挖的又一坑...
重启你的 Xcode 后,取消上面断点 Automatically continue after ...
的勾选, 执行点击并且断点以后,利用 pviews
后面跟上 UIView 对象的指针地址,即可查看当前视图的层级信息。比如 pviews 0x7f8744a14f40
,控制台则会打印:
<UIView: 0x7f8744a14f40;
| <TestGoodsImageView: 0x120979c10; baseClass = UIView;
| | <UIView: 0x120977ff0;
| | | <TestGoodsImageView: 0x12097bcf0; baseClass = UIImageView;
| <TestGoodsImageView: 0x1209892d0; baseClass = UIView;
| | <UIView: 0x1209894d0;
| | | <TestGoodsImageView: 0x120989c50; baseClass = UIImageView;
这样定位起来就更加简单了。
本文由 Bill 创作。
最后编辑时间为: 2020.08.03 at 09:13 am