Closed jiasongs closed 2 years ago
经过反复测试得知,只要不在+ (void)load
里hook@selector(layoutSubviews)
就会出现上述问题,反之则不会
QMUIDemoTest2.zip
根据 @ziecho 的分析,系统的 UIView 在 UIViewCommonInitWithFrame
时会判断当前的 layoutSubviews
是否为最初的 IMP,根据判断结果走不同的布局策略。而如果在 UIView 保存了最初的 IMP 后,业务代码再去 hook -[UIView layoutSubviews]
,就会导致某些系统 View 内部的判断认为 IMP 变了,走了预期之外的逻辑。通常这种情况不会导致什么问题,但在 issue 描述的这种场景里会出现死循环。
issue 的补充里说了“如果在 +load 里 hook 就不会出现问题”,是因为 +load 的时机比第一次触发 UIViewCommonInitWithFrame
还要早,所以 UIViewCommonInitWithFrame
里保存的就是你已经 hook 后的 IMP,就不影响原本的判断逻辑。
对于这个场景,我们暂时针对性地修复了,会跟随新版本发布,请关注。
Bug 表现 iPadOS,开启悬浮键盘的情况下,UIView使用qmui_layoutSubviewsBlock,会造成循环调用
截图
「_UIPopoverStandardChromeView」还有几个系统私有类一直不停的循环调用layoutSubviews
如何重现
self.textView.inputAccessoryView = UIView.new;
此DEMO中,QDTextViewController的58行做了测试代码,运行DEMO,进入QDTextViewController,点击输入框即可复现 QMUIDemoTest.zip
其他信息