iOS技术问询:UserDefaults的存储与操作是否为同步执行?
UserDefaults操作的同步性详解
嘿,这个问题问到点子上了,很多iOS开发者都会对UserDefaults的执行机制有点模糊,我来给你掰扯清楚:
1. 向UserDefaults存储数据是同步操作吗?
得分成内存更新和磁盘持久化两个层面来看:
- 内存层面是同步的:调用
set(_:forKey:)时,会立即同步更新UserDefaults在内存中的缓存字典,这一步是在当前调用线程上同步完成的,不会异步执行。 - 磁盘持久化是异步延迟的:内存中的数据并不会立刻写入磁盘,iOS系统会在合适的时机(比如App进入后台、系统空闲时)批量将UserDefaults的变更写入磁盘,这个过程是后台异步执行的,不会阻塞当前线程。
补充:以前我们会用
synchronize()方法强制触发磁盘写入,但iOS 10之后这个方法被标记为过时了——苹果官方表示系统会自动处理磁盘同步,手动调用可能会带来不必要的性能开销。如果是特别关键的数据需要确保写入磁盘,现在可以考虑用其他更可靠的持久化方案(比如FileManager直接写文件),或者依赖系统的自动持久化逻辑。
2. UserDefaults的各类操作是否均为同步执行?
大部分核心操作(比如set、object(forKey:)、removeObject(forKey:)等)在内存层面都是同步执行的,也就是说:
- 同一线程内的操作会严格按照代码顺序执行,后一个操作会等待前一个操作完成内存更新后才会开始。
拿你给出的代码举例:
UserDefaults.standard.set(myValue1, forKey: "myValue1") UserDefaults.standard.set(myValue2, forKey: "myValue2")
这两行代码在调用线程上是顺序同步执行的:
- 先执行第一行,把
myValue1同步写入内存缓存; - 第一行执行完成后,才会执行第二行,把
myValue2写入内存缓存。
如果你在这两行之后立刻读取这两个key的值:
let value1 = UserDefaults.standard.object(forKey: "myValue1") let value2 = UserDefaults.standard.object(forKey: "myValue2")
能保证拿到的都是最新设置的值,因为内存更新已经同步完成了。
不过要注意:跨线程的操作没有内置的线程安全保障,如果多个线程同时读写UserDefaults,可能会出现数据竞争问题,这时候需要你自己加锁(比如用DispatchQueue的串行队列来包裹操作)。
内容的提问来源于stack exchange,提问作者Micro
相关产品推荐
相关产品推荐

