我发布了这个问题(连同答案),以便其他人可以从我已经进化到让模块自动检测(并响应)iOS 应用程序状态更改的巧妙技术中受益。(格式化的)博客讨论在这里我的博客
1 回答
如果您在谷歌上搜索让代码执行以响应应用程序状态更改的解决方案,您会发现代码示例,您可以在其中将代码调用添加到应用程序委托中,因为每当应用程序 didFinishLaunchingWithOptions、didBecomeActive 或 WillEnterBackground 时都会调用它.
但是,假设您开始开发另一个应用程序,该应用程序重用了您的大量代码。如果您可以只复制一些文件并获得所有功能,而不必担心重新连接应用程序委托方法,那不是很好吗?
总而言之,我们想要插入式模块,仅凭借在项目中的优点,就可以执行它们的工作,而无需任何额外的努力或接线。此时您可能会说“我也希望独角兽和精灵给我带来披萨”。忍受我。
我不确定在阅读文档时我是如何错过这一点的,但是当 iOS 应用程序更改状态时,不仅仅是应用程序委托知道它。NSNotifications 也会发布所有主要的状态变化。以下是直接取自 api 参考的文本:
调用 [applicationDidBecomeActive] 后,应用程序还会发布 UIApplicationDidBecomeActiveNotification 通知,让感兴趣的对象有机会响应转换。
同样,有一个 UIApplicationDidFinishLaunchingNotification 会在应用程序完成启动后立即发布,还有其他用于进入后台或进入前台的通知。
所以这简化了我们的代码:而不是必须调用
[RobustWebService handleAppBecomingActive]
在应用程序委托的 applicationDidBecomeActive 实现中,我们只需要让 RobustWebService 响应 UIApplicationDidFinishLaunchingNotification。
现在考虑一下,您可能会意识到,为了让 RWS 类处理通知,它必须注册为观察者。那个电话看起来像
[[NSNotificationCenter defaultCenter] addObserver:self
Selector:@selector(handleAppBecomeActive)
name:UIApplicationDidFinishLaunchingNotification
object :nil]
那在哪里可以完成?请记住,我们不想接触应用程序委托,因为这会破坏拥有独立插件模块的意图。如果只有某种方法可以让类的 addObserver 函数调用自动发生。要是……</p>
这时候我们就不得不退出“Cocoa”,深入研究Objective-C的底层技术。果然,有一个名为“load”的类方法,如果它出现在你的类定义中,它将在第一次加载类时自动调用。让我们在代码中重申这一点。如果您在任何 class.m 文件中编写此函数
+ (void) load
{
// stuff
}
它将在 iOS 加载类时运行。有趣的是,它在你的应用程序的 main() 例程被调用之前运行,所以你必须非常小心你试图做什么!此时您的大多数应用程序实际上并未启动并运行,但您可以保证您的类链接的所有框架也将首先加载。NSNotificationCenter 等框架,所以如果你在你的 class.m 中包含它
+ (void) load
{
[[NSNotificationCenter defaultCenter] addObserver:self
Selector:@selector(handleAppBecomeActive)
name:UIApplicationDidFinishLaunchingNotification
object :nil];
}
然后,当您的应用程序处于活动状态时,您的 handleAppBecomeActive 方法将被调用,您无需执行任何操作,只需在项目中包含 class.h 和 class.m 即可。
如果您在 class.m 文件中包含此代码
+ (void) load;
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleAppLaunched)
name:UIApplicationDidFinishLaunchingNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleAppResigningActive) name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleAppBecomingActive) name:UIApplicationDidBecomeActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleAppEnteringBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleAppEnteringForeground) name:UIApplicationWillEnterForegroundNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleAppClosing) name:UIApplicationWillTerminateNotification object:nil];
}
您的班级将收到所有应用程序状态更改的通知,无需其他工作。这太酷了,它仍然让我感到刺痛。享受!
特里