Сбой при setValue:forKey:

#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) использовались, чтобы выяснить, что происходит.