iOS crash 'NSInternalInconsistencyException', reason: 'statement is still active' Core Data cache related?

Bob Spryn picture Bob Spryn · Mar 1, 2012 · Viewed 11.9k times · Source

Very occasionally seeing these pop up in crash reports on screens using NSFetchedResultsController, and not sure how to address them. I don't believe I'm using threading anywhere, unless NSFetchedResults is using them internally.

'NSInternalInconsistencyException', reason: 'statement is still active' is the full explanation I get.

Two recent stack traces:

0   CoreFoundation                      0x37a368bf __exceptionPreprocess + 163
1   libobjc.A.dylib                     0x3151c1e5 objc_exception_throw + 33
2   CoreData                            0x340b2ea5 -[NSSQLiteStatement cachedSQLiteStatement] + 1
3   CoreData                            0x340b274f -[NSSQLiteConnection prepareSQLStatement:] + 55
4   CoreData                            0x34156049 -[NSSQLChannel selectRowsWithCachedStatement:] + 61
5   CoreData                            0x34181d63 newFetchedRowsForFetchPlan_MT + 783
6   CoreData                            0x340bab07 -[NSSQLCore newRowsForFetchPlan:] + 351
7   CoreData                            0x34160011 -[NSSQLCore fetchRowForObjectID:] + 1005
8   CoreData                            0x340cca57 -[NSSQLCore newValuesForObjectWithID:withContext:error:] + 195
9   CoreData                            0x340cbf83 _PFFaultHandlerLookupRow + 423
10  CoreData                            0x340cba97 _PF_FulfillDeferredFault + 187
11  CoreData                            0x340cb94f _sharedIMPL_pvfk_core + 39
12  PowerPro                            0x0006a779 -[GuestCard getPrimaryProspectiveTenant] (GuestCard.m:77)
13  PowerPro                            0x00017bf9 -[OutstandingFollowupsViewController configureCell:atIndexPath:] (OutstandingFollowupsViewController.m:208)
14  PowerPro                            0x00017b9b -[OutstandingFollowupsViewController tableView:cellForRowAtIndexPath:] (OutstandingFollowupsViewController.m:203)

Last Exception Backtrace:
0   CoreFoundation                      0x37a368bf __exceptionPreprocess + 163
1   libobjc.A.dylib                     0x3151c1e5 objc_exception_throw + 33
2   CoreData                            0x340b2ea5 -[NSSQLiteStatement cachedSQLiteStatement] + 1
3   CoreData                            0x340b274f -[NSSQLiteConnection prepareSQLStatement:] + 55
4   CoreData                            0x34156049 -[NSSQLChannel selectRowsWithCachedStatement:] + 61
5   CoreData                            0x340c26eb -[NSSQLCore _newRowsForFetchPlan:selectedBy:withArgument:] + 515
6   CoreData                            0x340bab3f -[NSSQLCore newRowsForFetchPlan:] + 407
7   CoreData                            0x3415ea55 -[NSSQLCore newFetchedPKsForSourceID:andRelationship:] + 2217
8   CoreData                            0x3416a935 -[NSSQLCore newValueForRelationship:forObjectWithID:withContext:error:] + 689
9   CoreData                            0x34108f8b -[NSFaultHandler retainedFulfillAggregateFaultForObject:andRelationship:withContext:] + 479
10  CoreData                            0x340dcb23 -[_NSFaultingMutableSet willRead] + 219
11  CoreData                            0x340dc70b -[_NSFaultingMutableSet count] + 23
12  PowerPro                            0x00016eb1 -[BrowseGuestCardsViewController configureCell:atIndexPath:] (BrowseGuestCardsViewController.m:246)
13  PowerPro                            0x00017173 -[BrowseGuestCardsViewController tableView:cellForRowAtIndexPath:] (BrowseGuestCardsViewController.m:222)
14  UIKit                               0x34e4e9cb -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:] + 547
15  UIKit                               0x34e4daa9 -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow:] + 1077
16  UIKit                               0x34e4d233 -[UITableView layoutSubviews] + 207
17  UIKit                               0x34df1d4b -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 183
18  CoreFoundation                      0x3799522b -[NSObject performSelector:withObject:] + 43
19  QuartzCore                          0x3318c381 -[CALayer layoutSublayers] + 217
20  QuartzCore                          0x3318bf99 CA::Layer::layout_if_needed(CA::Transaction*) + 217
21  QuartzCore                          0x3318bea5 -[CALayer layoutIfNeeded] + 153
22  UIKit                               0x34eb6fe1 -[UIButton titleLabel] + 73
23  PowerPro                            0x00017983 -[BrowseGuestCardsViewController viewDidLoad] (BrowseGuestCardsViewController.m:75)

Answer

Stuart Sharpe picture Stuart Sharpe · May 20, 2013

It's more than likely that this is a threading problem in some way or another. There isn't quite enough information in the question to see for sure, but it's worth check through the crash logs and looking at the stack traces for all threads at the time of the exception, and see if any other threads are doing anything which interacts with a managed object. It could be that you have a notification handler, a URL connection completion handler, or some other bit of code using concurrency which you hadn't noticed, using core data objects in the background. It's worth noting that setting or accessing any property on any managed object from a context that's being used on more than one thread could potentially trigger this kind of exception, which can make it pretty tough to diagnose.

The relatively simple solution to solving these problems in most apps is to push the execution of that code to the main thread (using dispatch_async()). Alternatively, if you've got lots of processing to do it might be better to create a child context on the background thread and re-fetch the object from the child context, then save the child context. Of course, to re-fetch the object you need to have its objectID, which is a property which can only be accessed on the thread the object was originally fetched on…