2013-07-26 1 views
2

У меня возникла проблема с CoreData, когда NSOperation, загружающий материал в фоновом режиме, освобождается.Ошибка при освобождении NSOperation в NSManagedObjectContext

Я использую вложенные управляемые контексты объектов и контекст операция использует всё охраняемый в -[NSManagedObjectContext performBlock:]

Однако, по времени операция неоспоримой высвобождена, я получаю аварию со следующим стеком:

#0 0x022d9098 in objc_msgSend() 
#1 0x00bfb903 in _PFObjectIDFastHash64() 
#2 0x029fbdb0 in __CFDictionaryHashKey() 
#3 0x029e13e2 in CFBasicHashFindBucket() 
#4 0x029e0e2d in CFDictionaryGetValue() 
#5 0x00c0a408 in -[NSPersistentStoreCache incrementRefCountForObjectID:]() 
#6 0x00c0a37e in -[NSSQLCore managedObjectContextDidRegisterObjectsWithIDs:]() 
#7 0x00cd378c in -[NSPersistentStoreCoordinator(_NSInternalMethods) _informAffectedStoresOfInterestByChildContextInObjectsWithObjectIDs:withSelector:]() 
#8 0x00c0a29f in -[NSPersistentStoreCoordinator(_NSInternalMethods) managedObjectContextDidRegisterObjectsWithIDs:]() 
#9 0x00cb41db in __95-[NSManagedObjectContext(_NestedContextSupport) managedObjectContextDidRegisterObjectsWithIDs:]_block_invoke_0() 
#10 0x00c39cc1 in internalBlockToNSManagedObjectContextPerform() 
#11 0x025af014 in _dispatch_client_callout() 
#12 0x0259ed5f in _dispatch_barrier_sync_f_invoke() 
#13 0x0259eaa3 in dispatch_barrier_sync_f() 
#14 0x00c39c8b in _perform() 
#15 0x00c3a6e9 in -[NSManagedObjectContext(_NestedContextSupport) managedObjectContextDidRegisterObjectsWithIDs:]() 
#16 0x00cb41db in __95-[NSManagedObjectContext(_NestedContextSupport) managedObjectContextDidRegisterObjectsWithIDs:]_block_invoke_0() 
#17 0x00c39cc1 in internalBlockToNSManagedObjectContextPerform() 
#18 0x025a0731 in _dispatch_barrier_sync_f_slow_invoke() 
#19 0x025af014 in _dispatch_client_callout() 
#20 0x0259f7d5 in _dispatch_main_queue_callback_4CF() 
#21 0x02a12af5 in __CFRunLoopRun() 
#22 0x02a11f44 in CFRunLoopRunSpecific() 
#23 0x02a11e1b in CFRunLoopRunInMode() 
#24 0x02dff7e3 in GSEventRunModal() 
#25 0x02dff668 in GSEventRun() 
#26 0x0120bffc in UIApplicationMain() 
#27 0x0000285d in main at /Users/mochs/Projects/12_IP_Lufthansa_Next/Lufthansa/Supporting Files/main.m:16 
#28 0x00002785 in start() 

Я действительно понятия не имею, что происходит. То, что я знаю:

  • Я использую ARC
  • Я с помощью вложенного управляемого объекта контексты
  • расписаний операции и выполняют вещи в общем NSThread со своим собственным runloop
  • Нити совместно и не освобождаются, когда операция уже высвобождена
  • Вскоре после того, как - [NSOperation dealloc] в приложении падает в основном потоке
  • я установил тот же вопрос несколько наших, прежде чем с [context reset] в методе dealloc NSOperation. В это время типа параллелизм был NSConfinementConcurrencyType, и я не использовал performBlock:
    • Из-за некоторые изменения мне нужно изменить тип параллелизма в контексте NSPrivateQueueConcurrencyType и сделать его использовать performBlock:, теперь ошибка возвращается.

Я уверен, что призыв к reset не реально решить эту проблему, но вместо этого просто фиксируя аварии. Я понятия не имею, что действительно приводит к такой катастрофе.

Кто-нибудь знает, о чем идет речь?

С наилучшими пожеланиями, Майкл

+0

* «Вскоре после этого [NSOperation dealloc] приложение вылетает ...» *. Что это значит? Вы называете dealloc? Если нет, то откуда вы знаете? –

+0

Я установил там точку останова. После этого, похоже, что-то происходит с контекстом основного потока, и он падает. –

+1

Трудно сказать наверняка.Обратный ход выглядит так: 'executeBock:' не выполнялся, и произошел сбой в этом блоке. Вызов 'reset' предположительно отменяет' performBlock: '. Может быть, у вас есть 'performBlock:' где-то, что полагается на очередь операций, которая все еще существует, и сработает, если это не так? –

ответ

0

Наконец-то я нашел проблему. При сохранении всех контекстов до постоянного хранилища используется метод saveToPersistentStore:, который я использовал от RestKit, с некоторыми незначительными изменениями, соответствующими нашим требованиям.

Следующая строка, которая должна работать в качестве исправления на iOS5, вызвал вопрос, по крайней мере, на iOS6:

[contextToSave obtainPermanentIDsForObjects:[[contextToSave insertedObjects] allObjects] error:&localError]; 

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

+0

Что сказала ошибка? – Mundi

+0

@Mundi, какая ошибка? Вы имеете в виду исправление в 'RestKit'? Это оригинальная реализация с объяснением ошибки: https://github.com/RestKit/RestKit/blob/d97c07acc2142e5912da9e79e9086bb2686d4ac8/Code/CoreData/NSManagedObjectContext%2BRKAdditions.m#L39 –

+0

Переменная 'localError' выше. – Mundi

0

Насколько я знаю основные данные не поточно. На github вы можете найти эти расширения, которые сделают потоки данных Core Data безопасными Adam Roth

+0

Как я уже говорил выше: я использую методы 'performBlock:' и метод '-initWithConcurrencyType:' для инициализации контекста! –

+0

Ops, извините .. У меня была аналогичная проблема в менеджере загрузки, проблема была вызвана неправильной последовательностью установки завершенного и отмененного свойства в подклассе NSOperation в NSOperationQueue. Я также открыл вопрос http://stackoverflow.com/questions/9409994/cancelling-nsoperation-from-nsoperationqueue-cause-crash – Andrea

 Смежные вопросы

  • Нет связанных вопросов^_^