So that I don't bury the lede, I'm going to open with my core question: why is it that my NSFetchedResultsController's fetchedObjects array is usually homogeneous, but on rare occasions contains an __NSCFString
among the managed objects it should contain?
I have an app that has been in production for a long, long time. It's primary view is a table view that contains a list of videos, backed by core data managed objects. The table view controller uses an NSFetchedResultsController
configured with a fairly ordinary NSFetchRequest
:
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:[ABCVideo entityName]];
NSString *sectionKeyPath = nil;
request.fetchBatchSize = 20;
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:ABCVideoAttributes.recordingDate ascending:NO];
sectionKeyPath = @"sectionIdentifier";
request.sortDescriptors = @[sort];
request.predicate = [NSPredicate predicateWithFormat:@"owner = %@ and %K = %@", person, ABCVideoAttributes.serverDeleted, @(NO)];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:moc sectionNameKeyPath:sectionKeyPath cacheName:kABCMyVideosTableViewControllerCacheKey];
Since these videos can be uploaded into the cloud, this table view controller gets occasional notifications to update progress bars in the table view cells corresponding to videos that are currently being uploaded. Inside this callback, we are getting the NSFetchedResultsController
's fetchedObjects
array to find the video corresponding to the notification, so that the correct table view cell can update its progress bar.
This all works. 99.9% of the time, it works every time </RonBurgundy>
.
But I noticed in our HockeyApp crash reports that there is a rare, rare case where I was getting a SIGABRT that happens when my notification handler is trying to get a filteredArrayUsingPredicate
from the fetchedObjects
:
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFString 0x136f24480> valueForUndefinedKey:]: this class is not key value coding-compliant for the key guid.'
Recently I managed to find a case where I could occasionally reproduce this crash, and after a lot of experimentation, I discovered that the fetchedObjects
array sometimes contained something that wasn't an ABCVideo
: instead, one slot in the array was occupied by a __NSCFString
instance. This was pretty suprising, given that the NSFetchRequestResultType
is of NSManagedObjectResultType
, and a string is not a managed object.
So I'm left wondering: is this a Core Data bug? Or does my array contain a pointer that formerly pointed to an ABCVideo
instance that was deallocated and that location on the heap was subsequently taken by a __NSCFString
instance? If it's the latter, then how could this happen? I'm using ARC, so it's hard to understand how one of these videos could become deallocated.