iOS NSUserDefaults access before synchronize compl

2019-01-20 17:20发布

问题:

If I set an NSUserDefault object and try to access it before it has been synchronized, will I be able to access the object I just added?

I've tried writing code to test it but I'm unsure of if the synchronization is happening without me knowing it.

回答1:

Yes, your application can access the saved preferences before the synchronize happens, if it is saved before the read cycle happens during the same run session of the application. For accessing the information during subsequent app launches it is necessary that the synchronisation happens.

From the Apple docs: NSUserDefaults

NSUserDefaults caches the information to avoid having to open the user’s defaults database each time you need a default value. The synchronize method, which is automatically invoked at periodic intervals, keeps the in-memory cache in sync with a user’s defaults database.

The synchronize method writes any modifications to in-memory cache to the disk (plist file in Library/Preferences) and updates the unmodified in-memory cache to the latest on disk. This method gets invoked at periodic intervals, without the app getting notified.

From docs again: [NSUserDefaults synchronize]

Discussion
Because this method is automatically invoked at periodic intervals, use this method only if you cannot wait for the automatic synchronization (for example, if your application is about to exit) or if you want to update the user defaults to what is on disk even though you have not made any changes.

In my experience, call the synchronize method explicitly when application is going to exit, this ensures that the latest preferences are available on next launch. However, I have also come across scenarios when application crashes before the synchronize happens so the pref are not stored. Your application must be able to handle these scenarios.

Additional
Use the NSUserDefaults to store minimal data, do not store huge data. Reason is, the app defaults are loaded during the app launch, if the data to load is huge then the app loading time increases and chances are that the app is killed by the Springboard.



回答2:

The purpose of [NSUserDefault synchronize]; is to make the user defaults get written on disk immediately.

Regarding this:

I'm unsure of if the synchronization is happening without me knowing it.

You don't need to call [NSUserDefault synchronize] explicitly to store the value, iOS already does it at appropriate time (like when going into background). So you can avoid that line unless you want to store that value immediately. In fact, it's a performance problem if you call synchronize every time you set a value.