iOS开发中单例模式的静态对象何时会被自动释放?
iOS静态单例内存机制与写法安全性解答
单例内存是否会被自动释放
你使用静态内存存储的单例,在APP进程存活期间不会被系统单独回收释放,不存在长时间离开APP就自动清空单例内存、丢失临时数据的情况。
系统不会在进程运行过程中主动清理某个静态变量持有的内存,所有进程内的内存回收都只会针对对象引用计数为0的实例,你声明的静态常量对单例实例是默认强持有,引用计数永远大于0,不会被系统自动释放。
单例内存的释放时机
单例占用的内存只有在以下场景才会被回收:
- 用户手动上滑关闭APP,进程被终止
- 系统在内存压力过高、或者APP在后台停留超时时,主动杀掉后台挂起的APP进程
内存回收时单例存储的所有临时数据会随进程销毁完全丢失,没有任何回调可以提前感知这个过程。
数据丢失的发生概率
- 短时间切后台(比如切出APP接电话、回消息,停留时间在几小时内):当前iOS设备内存普遍充足,进程被系统杀掉的概率极低,单例数据基本不会丢失
- 长时间停留在后台(比如隔了大半天、一两天再切回APP)、或者用户在前台开了多个高内存占用应用:系统为了保障前台应用流畅度,会优先回收后台挂起进程,此时单例数据丢失概率会明显升高,具体概率和设备剩余内存、系统内存调度策略相关,没有固定统计值。
给出的单例写法安全性验证
你提供的实现代码如下:
class TestObject: NSObject { static let sharedInstance = TestObject() }
这个是Swift中最标准的线程安全单例写法,安全性完全满足开发要求:
- 静态let常量的初始化默认是懒加载逻辑,只有首次访问
sharedInstance时才会创建实例,不会占用启动期内存 - 初始化过程由系统底层的
dispatch_once机制保障,多线程并发访问时也只会创建一个实例,不会出现线程安全问题 - 静态常量对实例的强持有关系不会被意外打破,进程存活期间单例不会被意外释放
需要额外注意:不要把需要持久化的关键业务数据仅存在单例中,只要是进程被杀后不能丢失的数据,必须额外写入沙盒做持久化存储(比如UserDefaults、本地文件、数据库均可)。
内容的提问来源于stack exchange,提问作者Beginnerrrrrr
相关产品推荐
相关产品推荐

