#ios #objective-c #sqlite #core-data
#iOS #objective-c #sqlite #core-данные
Вопрос:
Crashlytics сообщил о сбое в моем приложении, и я понятия не имею, что происходит.
Вот трассировка стека:
Thread : Fatal Exception: NSInternalInconsistencyException
0 CoreFoundation 0x30080e83 __exceptionPreprocess 130
1 libobjc.A.dylib 0x3a3dd6c7 objc_exception_throw 38
2 CoreData 0x2fdcf941 -[NSSQLiteStatement cachedSQLiteStatement]
3 CoreData 0x2fdcf18d -[NSSQLiteConnection prepareSQLStatement:] 52
4 CoreData 0x2fde8edf -[NSSQLChannel selectRowsWithCachedStatement:] 58
5 CoreData 0x2fea8e1f newFetchedRowsForFetchPlan_MT 910
6 CoreData 0x2fde8949 -[NSSQLCore fetchRowForObjectID:] 1180
7 CoreData 0x2fde8311 -[NSSQLCore newValuesForObjectWithID:withContext:error:] 256
8 CoreData 0x2fde762b _PFFaultHandlerLookupRow 398
9 CoreData 0x2fde7193 _PF_FulfillDeferredFault 218
10 CoreData 0x2fdf6449 _PF_ManagedObject_WillChangeValueForKeyIndex 68
11 CoreData 0x2fdf636b _sharedIMPL_setvfk_core 110
12 CoreData 0x2fe1995d _PF_Handler_Public_SetProperty 92
13 CoreData 0x2fe1e2a9 -[NSManagedObject setValue:forKey:] 124
14 Application 0x0004dc45 -[DateFormatter storeValue:error:] (DateFormatter.m:65)
15 Application 0x0004ee17 -[Formatter storeValue:inObject:] (Formatter.m:176)
16 Application 0x0002b5c5 -[NSManagedObject(App) setValuesForKeysWithReceivedDictionary:] (NSManagedObject App.m:320)
17 Application 0x0002b8f3 -[NSManagedObject(App) setValuesForKeysWithReceivedDictionary:] (NSManagedObject App.m:377)
18 Application 0x0006352d -[ODataGetOperation processResult:] (ODataGetOperation.m:220)
19 Application 0x0004420b -[ODataOperation connectionDidFinishLoading:] (ODataOperation.m:741)
20 Foundation 0x309bb47f __65-[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:]_block_invoke 54
21 Foundation 0x309bb3c1 -[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:] 204
22 Foundation 0x309bb2dd -[NSURLConnectionInternal _withActiveConnectionAndDelegate:] 60
23 CFNetwork 0x2fceaf8f ___ZN27URLConnectionClient_Classic26_delegate_didFinishLoadingEU13block_pointerFvvE_block_invoke 74
24 CFNetwork 0x2fce9b8f ___ZN27URLConnectionClient_Classic18_withDelegateAsyncEPKcU13block_pointerFvP16_CFURLConnectionPK33CFURLConnectionClientCurrent_VMaxE_block_invoke_2 54
25 CFNetwork 0x2fd1b337 ___ZNK17CoreSchedulingSet13_performAsyncEPKcU13block_pointerFvvE_block_invoke 18
26 CoreFoundation 0x2ffb3ea1 CFArrayApplyFunction 36
27 CFNetwork 0x2fc81e05 RunloopBlockContext::perform() 164
28 CFNetwork 0x2fc81cd5 MultiplexerSource::perform() 220
29 CFNetwork 0x2fc81b65 MultiplexerSource::_perform(void*) 48
30 CoreFoundation 0x3004bf1f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ 14
31 CoreFoundation 0x3004b3e7 __CFRunLoopDoSources0 206
32 CoreFoundation 0x30049bd7 __CFRunLoopRun 630
33 CoreFoundation 0x2ffb4471 CFRunLoopRunSpecific 524
34 CoreFoundation 0x2ffb4253 CFRunLoopRunInMode 106
35 Foundation 0x309a2697 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] 254
36 Application 0x00043b4b -[ODataOperation send] (ODataOperation.m:548)
37 Application 0x0004277f -[ODataOperation operationWillStartPreparingData] (ODataOperation.m:131)
38 Foundation 0x30a5396d __NSOQSchedule_f 60
39 libdispatch.dylib 0x3a8c64b7 _dispatch_async_redirect_invoke 110
40 libdispatch.dylib 0x3a8c77d9 _dispatch_root_queue_drain 224
41 libdispatch.dylib 0x3a8c79c5 _dispatch_worker_thread2 56
42 libsystem_pthread.dylib 0x3a9f1dff _pthread_wqthread 298
43 libsystem_pthread.dylib 0x3a9f1cc4 start_wqthread 8
И есть последний метод, который вызывает setValue:forKey: в подклассе NSManagedObject
- (BOOL)storeValue:(void *)theValue error:(NSError **)theError
{
NSString * value = (__bridge NSString *)theValue;
NSString * errorMessage = nil;
if (![value length] amp;amp; !isOptional)
errorMessage = [NSString stringWithFormat: NSLocalizedString(@"Value cannot be nil or empty (Date) for field %@", @""), varName];
else
{
NSDate * date = nil;
if ([value length])
{
date = [NSDate dateWithISO8601: value];
if (!date)
errorMessage = [NSString stringWithFormat: NSLocalizedString(@"Invalid date %@ for field %@", @""), theValue, varName];
}
if (IvarAddress)
*((__strong NSDate **) IvarAddress) = date;
else
[currentObject setValue: date forKey: varName];
}
if (errorMessage)
{
if (theError)
*theError = [NSError errorWithDomain: AppDomain code: NSFormattingError userInfo: @{ NSLocalizedDescriptionKey: errorMessage }];
#ifdef DEBUG
NSLog(@"Formatter error: %@", errorMessage);
#endif
return NO;
}
return YES;
}
Я полностью открыт для любого предложения 🙂
Обновление: ключ существует, и устанавливаемое значение является NSDate, поэтому это атрибут NSManagedObject, а не отношение.
Обновление 2 :
У меня также есть еще один сбой с этим методом (трассировка стека не совсем одинакова) :
Thread : Fatal Exception: NSInternalInconsistencyException
0 CoreFoundation 0x30080e83 __exceptionPreprocess 130
1 libobjc.A.dylib 0x3a3dd6c7 objc_exception_throw 38
2 CoreData 0x2fddfacb -[NSSQLCore _obtainOpenChannel] 234
3 CoreData 0x2fea8ded newFetchedRowsForFetchPlan_MT 860
4 CoreData 0x2fde8949 -[NSSQLCore fetchRowForObjectID:] 1180
5 CoreData 0x2fde8311 -[NSSQLCore newValuesForObjectWithID:withContext:error:] 256
6 CoreData 0x2fde762b _PFFaultHandlerLookupRow 398
7 CoreData 0x2fde7193 _PF_FulfillDeferredFault 218
8 CoreData 0x2fdf6449 _PF_ManagedObject_WillChangeValueForKeyIndex 68
9 CoreData 0x2fdf636b _sharedIMPL_setvfk_core 110
10 CoreData 0x2fe1995d _PF_Handler_Public_SetProperty 92
11 CoreData 0x2fe1e2a9 -[NSManagedObject setValue:forKey:] 124
12 Application 0x000fcc45 -[DateFormatter storeValue:error:] (DateFormatter.m:65)
13 Application 0x000fde17 -[Formatter storeValue:inObject:] (Formatter.m:176)
14 Application 0x000da5c5 -[NSManagedObject(App) setValuesForKeysWithReceivedDictionary:] (NSManagedObject .m:320)
15 Application 0x000da8f3 -[NSManagedObject(App) setValuesForKeysWithReceivedDictionary:] (NSManagedObject .m:377)
16 Application 0x0011252d -[ODataGetOperation processResult:] (ODataGetOperation.m:220)
17 Application 0x000f320b -[ODataOperation connectionDidFinishLoading:] (ODataOperation.m:741)
18 Foundation 0x309bb47f __65-[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:]_block_invoke 54
19 Foundation 0x309bb3c1 -[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:] 204
20 Foundation 0x309bb2dd -[NSURLConnectionInternal _withActiveConnectionAndDelegate:] 60
Сообщение об исключении также отличается :
_obtainOpenChannel — NSSQLCore 0x15ef3780: канал базы данных недоступен
Но я думаю, что это две взаимосвязанные проблемы.
Комментарии:
1. Кажется, что-то не так с ключом в соответствии с официальным комментарием: если ключ не является свойством, определенным моделью, метод вызывает исключение. Если ключ идентифицирует отношение «к одному», связывает объект, указанный по значению, с получателем, не связывая ранее связанный объект, если он был. Учитывая объект коллекции и ключ, который идентифицирует отношение «ко многим», связывает объекты, содержащиеся в коллекции, с получателем, не связывая ранее связанные объекты, если таковые были.
2. Ключ существует, он соответствует атрибуту NSDate, а не взаимосвязи.
3. какой ключ вы используете — и какое сообщение об исключении
4. является ли свойство временным или сохраненным
5. Я не знаю, какой ключ использовался, но у меня много переходных процессов в модели, поэтому, если вы считаете, что это связано…
Ответ №1:
Итак, я, наконец, нашел причины, которые были связаны с проблемами многопоточности / параллелизма. В основном обновление одних и тех же объектов в двух потоках одновременно..
Недавно добавленные флаги отладки core data (-com.apple.Основные данные.ConcurrencyDebug 1) использовались, чтобы выяснить, что происходит.