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

11,917

Solution 1

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…

Solution 2

Got this error while simultaneously requesting data with NSFetchedResultController (from main thread context) and NSFetchRequest through my background context.

The way I have handled this is by making each of my MOCs have its own persistent store coordinator. Both of the persistent store coordinators talk to the same persistent store on disk.

Share:
11,917
Bob Spryn
Author by

Bob Spryn

Co-Founder / iOS Engineer at www.thumbworks.io

Updated on June 03, 2022

Comments

  • Bob Spryn
    Bob Spryn almost 2 years

    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)
    
  • MiKL
    MiKL almost 11 years
    I typically has this occurring when I tried to save a main ui context inside a performBlock executing on the private queue of one of its children...
  • Raj Pawan Gumdal
    Raj Pawan Gumdal almost 11 years
    +1 for "and see if any other threads are doing anything which interacts with a managed object"
  • Matt Fenwick
    Matt Fenwick about 8 years
    Is this true? "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 ..."