NSDateFormatter падает при использовании из разных потоков - PullRequest
17 голосов
/ 09 февраля 2011

Мы продолжаем получать случайное, странное падение с NSDateFormatter. Соответствующая трассировка стека:

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:] ()

Форматер даты все еще находится в памяти (т.е. не освобожден или поврежден). Единственное, о чем я могу думать, это то, что строки после сбоя не соответствуют формату, но я сомневаюсь, что это приведет к полному падению форматера. (нетрудно проверить формат заранее).

Есть мысли?

Ответы [ 5 ]

44 голосов
/ 10 февраля 2011

Спасибо предыдущим ответчикам.

Это не было проблемой с памятью. Это оказалось проблемой синхронизации. NSDateFormatter s не являются потокобезопасными; был фоновый поток, пытающийся использовать один и тот же форматер одновременно (отсюда случайность).

Надеюсь, это поможет кому-то в будущем!

4 голосов
/ 21 апреля 2012

Другим решением было бы сериализовать выполнение кода, который использует NSDateFormatter s, или любых других не поточно-ориентированных объектов.Используя Grand Central Dispatch, вы можете вставить код в main_queue:

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

или использовать личную очередь для достижения того же эффекта:

dispatch_queue_t dispatch_queue = dispatch_queue_create("com.MyApp.serializer",NULL);
dispatch_async(dispatch_queue, ^(void){
  [some_object some_message];
});
1 голос
/ 15 марта 2013

У меня были странные сбои с _sigtramp, которые приводили к тому, что приложение отображалось заблокированным, но все еще на экране - полностью препятствуя истинной основной причине.

Оказалось, что мы ввели многопоточный анализ данных, которыйстолкнулся с основным потоком GUI, пытаясь разобрать даты с помощью NSDateFormatter.

Установка некоторой синхронизации вызовов NSDateFormatter formatDate позволила решить проблемы.

1 голос
/ 09 февраля 2011

Спорим, что строка, которую вы передаете форматировщику даты, переиздана

1 голос
/ 09 февраля 2011

EXCBADACCESS произойдет, когда вы используете любой освобожденный объект ... Попробуйте использовать NSZombie. Это простой способ узнать, где происходит EXCBADACCESS ... Он укажет, какой метод, где и какой объект освобожден

Смотрите эту ссылку http://www.markj.net/iphone-memory-debug-nszombie/

...