Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is NSUserDefaults threadsafe

I know that documentation says that it is, and i know that this subject was already under discussion but I have an interesting stack result and I cant conclude anything else but that [NSUserDefaults standardUserDefaults] is not threadsafe. So I will post my crash log and hope that somebody sees something that I can't...

Crashed Thread

    ... 
    libdispatch.dylib 0x3ab53d67 _dispatch_client_callout + 23
    libdispatch.dylib 0x3ab65e73 _dispatch_barrier_sync_f_invoke + 27
    CoreFoundation 0x302b470d CFPreferencesAppSynchronize + 265       
    Foundation 0x30151b01 -[NSUserDefaults(NSUserDefaults) synchronize] + 25
    MyApp 0x0009df8b -[AppDelegate applicationDidEnterBackground:] (AppDelegate.m:178)
    ...
    MyApp 0x0005344b main (main.m:17)
    MyApp 0x000533f8 start + 40

some other thread

    ...
    CoreFoundation 0x302bc13f _CFXPreferencesSetValue + 107
    CoreFoundation 0x302bc039 CFPreferencesSetAppValue + 41
    Foundation 0x30c76935 -[NSUserDefaults(NSUserDefaults) setObject:forKey:] + 61
    MyApp 0x000b2e9d -[AppData parserDidEndDocument:] (AppData.m:1013)
   ...

Parts of the stack have been cut out and substituted with "..." cause its just too long and irrelevant for the subject. App crashes with message:

* Collection <__NSDictionaryM: 0x15a04ae0> was mutated while being enumerated. ....

Code: AppDelegate: -> crached thread...

    - (void)applicationDidEnterBackground:(UIApplication *)application
    {
        [[NSUserDefaults standardUserDefaults] synchronize];
    }

MyClass: ->second thread:

    -(void)parserDidEndDocument:(NSXMLParser *)parser {
    ...
        [[NSUserDefaults standardUserDefaults] setObject:arr forKey:@"savedStations"];
        [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:@"lastUpdateDate"];
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"alreadyLoaded"];
    ...
    }

I have this crash in couple of other cases, it always includes some writing to user defaults in one thread and synchronizeing in other thread that crashes.. If anyone has some other explanation I would be very greatfull...

like image 209
AntonijoDev Avatar asked Oct 21 '13 09:10

AntonijoDev


People also ask

What is NSUserDefaults?

A property list, or NSUserDefaults can store any type of object that can be converted to an NSData object. It would require any custom class to implement that capability, but if it does, that can be stored as an NSData. These are the only types that can be stored directly.

How much data can you store in UserDefaults?

There is no specific number attached to “a small amount”, but everything you store in UserDefaults will automatically be loaded when your app launches – if you store a lot in there your app launch will slow down. To give you at least an idea, you should aim to store no more than 512KB in there.

What should I store in user defaults?

You can use UserDefaults to store any basic data type for as long as the app is installed. You can write basic types such as Bool , Float , Double , Int , String , or URL , but you can also write more complex types such as arrays, dictionaries and Date – and even Data values.

How do you save NSUserDefaults in Objective C?

Saving to NSUserDefaults : Basically, all you have to do is load NSUserDefaults, and then tell it to save a value to a specific key. Here is a simple example of writing an integer to NSUserDefaults: NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];


1 Answers

The NSUserDefaults class is thread-safe.

(c) https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/index.html

like image 56
Nekto Avatar answered Dec 01 '22 22:12

Nekto