Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSDateFormatter crashes when used from different threads

We keep getting a random, weird crash with NSDateFormatter. The relevant stack trace is:

Program received signal:  “EXC_BAD_ACCESS”.
#0  0x00000005 in ?? ()
#1  0x0213e3c3 in udat_parse ()
#2  0x01d4e1ca in CFDateFormatterGetAbsoluteTimeFromString ()
#3  0x01d4e225 in CFDateFormatterCreateDateFromString ()
#4  0x003e2608 in getObjectValue ()
#5  0x003e2921 in -[NSDateFormatter getObjectValue:forString:errorDescription:] ()
#6  0x003e21cd in -[NSDateFormatter dateFromString:] ()

The date formatter is still in memory (i.e. not released or corrupted). The only thing I can think of is the strings upon crash do not conform to the format, but i doubt that will make the formatter completely crash. (it is non trivial to check the format beforehand).

Any thoughts?

like image 982
jbenet Avatar asked Feb 09 '11 12:02

jbenet


2 Answers

Thanks to the previous answerers.

This was not a memory problem. It turned out to be a synchronization issue. NSDateFormatters are not thread safe; there was a background thread attempting to use the same formatter at the same time (hence the randomness).

Hope this helps someone in the future!

like image 120
jbenet Avatar answered Oct 08 '22 22:10

jbenet


Another solution would be to serialize the execution of the code that uses NSDateFormatters, or any other non-thread-safe objects. Using Grand Central Dispatch you can push the code on the main_queue:

dispatch_async(dispatch_get_main_queue(), ^(void){
  [some_object some_message];
});

or use a private queue to achieve the same effect:

dispatch_queue_t dispatch_queue = dispatch_queue_create("com.MyApp.serializer",NULL);
dispatch_async(dispatch_queue, ^(void){
  [some_object some_message];
});
like image 25
kadam Avatar answered Oct 08 '22 23:10

kadam