【问题标题】:Core Data crash NSInternalInconsistencyException 'statement is still active'核心数据崩溃 NSInternalInconsistencyException 'statement is still active'
【发布时间】:2015-04-21 03:07:24
【问题描述】:

我有两个托管对象上下文共享同一个持久存储协调器:

  • 一个带有NSMainQueueConcurrencyType 的主线程和
  • NSPrivateQueueConcurrencyType 用于进行后台处理。

所有数据解析工作都发生在针对私有队列的 performBlock 调用中,并通过NSManagedObjectContextDidSaveNotification 合并到主线程上以进行 UI 更新。

我启用了 Core Data 多线程断言,当崩溃发生时它们永远不会触发。

当我在后台上下文工作时推入具有NSFetchedResultsController 的新视图时,我偶尔会遇到显示statement is still active 的崩溃。崩溃将在获取结果控制器的获取时触发,或者在存储数据的代码中触发。当它在数据解析部分崩溃时,它总是在一对多关系中失败。

到目前为止,这些崩溃都是 100% 的 iOS 8,我从未在 7 上看到过。

我的问题是这样的:假设我没有违反线程限制(断言应该大声喊叫,并且没有......)还有什么明显的我可以做这会导致主线程上下文在后台线程正在处理持久存储的过程中崩溃?

Crashlytics 是这样说的:

Thread : Fatal Exception: NSInternalInconsistencyException
0  CoreFoundation                 0x00000001871e659c __exceptionPreprocess + 132
1  libobjc.A.dylib                0x00000001978f00e4 objc_exception_throw + 60
2  CoreData                       0x0000000186e97c6c -[NSSQLiteStatement cachedSQLiteStatement]
3  CoreData                       0x0000000186e9739c -[NSSQLiteConnection prepareSQLStatement:] + 76
4  CoreData                       0x0000000186eb3810 -[NSSQLChannel selectRowsWithCachedStatement:] + 76
5  CoreData                       0x0000000186f9e7a4 newFetchedRowsForFetchPlan_MT + 1100
6  CoreData                       0x0000000186ecf948 -[NSSQLCore newFetchedPKsForSourceID:andRelationship:] + 2120
7  CoreData                       0x0000000186ecea24 -[NSSQLCore newValueForRelationship:forObjectWithID:withContext:error:] + 616
8  CoreData                       0x0000000186f67480 __110-[NSPersistentStoreCoordinator(_NSInternalMethods) newValueForRelationship:forObjectWithID:withContext:error:]_block_invoke + 80
9  CoreData                       0x0000000186f6d654 gutsOfBlockToNSPersistentStoreCoordinatorPerform + 180
10 CoreData                       0x0000000186f60ccc _perform + 204
11 CoreData                       0x0000000186ece730 -[NSPersistentStoreCoordinator(_NSInternalMethods) newValueForRelationship:forObjectWithID:withContext:error:] + 160
12 CoreData                       0x0000000186ece4d8 -[NSFaultHandler retainedFulfillAggregateFaultForObject:andRelationship:withContext:] + 716
13 CoreData                       0x0000000186ef15ec -[_NSFaultingMutableSet willReadWithContents:] + 444
14 CoreData                       0x0000000186ed146c -[_NSFaultingMutableSet count] + 32
15 CoreData                       0x0000000186ecd234 -[NSManagedObject(_NSInternalMethods) _didChangeValue:forRelationship:named:withInverse:] + 440
16 Foundation                     0x0000000187fe1a14 NSKeyValueNotifyObserver + 340
17 Foundation                     0x0000000187fe1534 NSKeyValueDidChange + 460
18 Foundation                     0x0000000187fcaac4 -[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] + 116
19 CoreData                       0x0000000186ec4e90 _PF_ManagedObject_DidChangeValueForKeyIndex + 140
20 CoreData                       0x0000000186ec3248 _sharedIMPL_setvfk_core + 284
21 My App                     0x00000001000f0b00 -[LocationAdapter processBuildingList:context:completion:] (LocationAdapter.m:134)

【问题讨论】:

  • 您是否使用完成块来响应后台上下文完成某些操作?如果是这样,请查看this question
  • 我确实有一个完成块,它最终会在主线程上触发一些 UI 工作,但它只被调用一次。
  • 这是在模拟器上测试还是在设备上测试时发生的?这是否在您更新 CoreData 模型后开始发生?
  • 只是为了检查,尝试在您从商店保存/读取的行周围添加@syncronize,看看崩溃是否停止。如果它停止,您有多个线程试图访问存储。
  • 你终于弄明白了吗?

标签: ios objective-c core-data nsmanagedobjectcontext


【解决方案1】:

我最终改变了创建核心数据堆栈的方式,但这种情况消失了。移动到持久存储上下文、子 UI 上下文和孙子背景上下文并适当地保持链向上使这一切变得更好。我仍然不能 100% 确定为什么原始设置不适用于 8。

【讨论】:

    【解决方案2】:

    您可以使用 nsmanaged 对象上下文的副本作为 nsmanagedobject 上下文的新实例。 对于每个托管对象上下文,你应该像这样使用你想要保存多线程中的不一致性

    [backgroundMOC performBlockAndWait:^{
        // read/write operation
        [backgroundMOC saveContextWithMOC:backgroundMOC];
    }];
    

    // 主线程 MOC

    [mainMOC performBlockAndWait:^{
        // read/write operation
        [backgroundMOC saveContextWithMOC:backgroundMOC];
    }];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      • 2014-11-09
      • 2023-03-14
      • 2018-09-02
      • 2023-03-10
      • 1970-01-01
      相关资源
      最近更新 更多