背景
至于为什么您会在通知触发中看到这种差异,这可能与 KVO 的工作方式有关。你观察一个属性的值。在这种情况下,statusBarHidden
。但是,为了获得通知,该属性必须通过为其存在的设置器进行更改。
通知不会神奇地发生,因此需要将其有效地编码为 setter 的副作用。(这通常在对属性进行编码时自动为您完成)但是,具有该属性的类也可以选择直接修改ivar。在这种情况下,UIApplication
有/有一个内部结构_applicationFlags
,其中包含
unsigned int statusBarHidden:1;
因此,完全有可能setStatusBarHidden:withAnimation:
只是直接修改底层数据成员,这绕过了回调观察者所需的设置器。
解决方案?
就您的解决方法而言,您没有提及此应用程序是否适用于应用程序商店(可能是出于个人/爱好目的,可能是企业应用程序,也可能是越狱应用程序)。
您可能会选择的一件事是使用方法调配setStatusBarHidden:withAnimation:
来用您自己的方法替换默认实现。您自己的实现可以简单地调用setStatusBarHidden:
,然后重新启用 KVO。或者,如果您想保留动画,您可以使用 GCD 安排在完成动画setStatusBarHidden:
所需的时间之后运行。setStatusBarHidden:withAnimation:
这样,您仍然可以获得动画,并且还可以通过调用来触发 KVO setStatusBarHidden:
。
我不清楚 App Store 应用程序中是否总是拒绝方法调配。我认为是(至少,在 iOS 框架中混合方法时),但据此,它要么是允许的,要么可以通过.
下一个问题是,“如果方法调配真的是 Apple 希望你避免的事情,尽管它在公共 API中,有没有办法解决这个问题?”
除非我链接到的 Stack Overflow 问题中的人在撒谎,否则它看起来确实通过了审查(至少有时是这样)。所以,也许它没有以自动化的方式进行测试。也许它有时会被人类测试人员视觉识别,他们认为标准功能的工作方式不同,他们推断一定是方法混搭的结果。在这种情况下,您实际上并不想使用它来更改状态栏 UI 行为,只是为了锁定通知,因此不应该打扰他们。
或者,他们可能正在搜索已知 iOS API 的选择器(与 swizzling 一起使用)。如果是这种情况,从字符串构建的选择器很容易被混淆,以避免检测。
无论如何,只是一些选择......