iOS应用挂起时是否有类似UIApplicationDidEnterBackground的通知?
好问题!首先得理清iOS应用的状态流转逻辑:当你的应用进入后台后,会先处于后台活跃状态(此时还能执行有限的代码,比如你提到的蓝牙、定位相关逻辑);当系统资源紧张时,才会把应用转入挂起状态——这个状态下,应用的所有执行都会暂停,进程被冻结,直到系统再次唤醒它(比如有蓝牙事件、定位更新触发)或者用户重新打开应用。
核心结论:没有专门的挂起通知
因为挂起状态下应用代码完全停止运行,系统不可能给你发送通知让你处理——你根本没机会执行接收通知的代码。
间接感知挂起状态的方法
虽然没有直接通知,但你可以通过以下几种方式间接判断应用是否经历了挂起:
唤醒时检查应用状态:当你的应用因为蓝牙事件、定位更新等被系统唤醒回到后台活跃状态时,可以在对应回调方法里检查
UIApplication.shared.applicationState的取值。如果之前的状态是.suspended,就说明应用刚刚从挂起状态被唤醒。比如在CoreBluetooth的连接回调或者CLLocationManager的定位更新方法里做这个检查。利用后台任务的过期回调:如果你启动了后台任务(通过
UIApplication.shared.beginBackgroundTask(expirationHandler:)),当系统即将挂起或终止你的应用时,会触发这个expirationHandler回调。在这个回调里,你可以知道应用马上要被挂起,从而做一些收尾工作(比如保存数据、释放资源)。观察特定框架的回调中断:比如你使用CLLocationManager时,如果开启了后台定位更新,当应用被挂起后,定位的委托方法(比如
locationManager(_:didUpdateLocations:))会停止调用;当应用被唤醒后,这些回调会恢复。你可以通过监测回调的中断和恢复,间接判断应用是否经历了挂起。同理,CoreBluetooth的回调也会在挂起时停止,唤醒后恢复。
针对你的场景补充
对于依赖蓝牙、定位后台运行的应用,你不需要“实时”获知挂起状态——因为挂起时你什么也做不了。更重要的是在应用被唤醒时,检查状态并恢复之前的逻辑,同时在后台任务过期时做好收尾,确保数据不会丢失。
内容的提问来源于stack exchange,提问作者Paul T.

