【发布时间】: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