Etep
Etep

Reputation: 543

NSFetchedResultController Modifying Core Data In Modal View

I'm encountering a crash when I insert a new entry into Core Data from a modal view.

-[MyObject compare:]: unrecognized selector sent to instance

libc++abi: terminating with uncaught exception of type NSException
dyld4 config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/Developer/usr/lib/libBacktraceRecording.dylib:/Developer/usr/lib/libMainThreadChecker.dylib:/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MyObject compare:]: unrecognized selector sent to instance 0x282706ee0'
terminating with uncaught exception of type NSException
From all the reading I found this can be caused by the predicate or the sort descriptor and indeed in this case, it's the sort descriptor because if I remove it, the crash doesn't happen. But what I have is two different NSFetchedResultControllers in the view which I think is the root cause. Here's how its setup.

We have three Core Data Entities

Blog Post BlogHasPost (has a relationship to Blog and Post)

The reason for "BlogHasPost" is because not only is it a many to many relationship but it also has extra data in it relating to some position and permission data. Therefore it had to be it's own table rather than just creating a many relationship on both Blog and Post.

View A (let's call it BlogView) and makes use of NSFetchedResultsController. The fetchRequest is set to BlogHasPost. I have a sort descriptor set to Blog so that I will get all the BlogHasPost objects related to a particular Blog. Then in the cellForRowAtIndexPath I'm able to show the Post data based on this entity.

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"blog" ascending:YES];
    [sortDescriptors addObject:sortDescriptor];
    [fetchRequest setSortDescriptors:sortDescriptors];

This works and when BlogView is shown it shows a nice table listing all the Posts. So all good there.

Then the user can tap a button to create a new Post. This opens up the NewPost view on top of the BlogView modally. Therefore both views are still active.

A Post object is created and the user is able to put in their data. One of the fields is to associate it to pick which "blogs" it should be part of. For each association a BlogHasPost object is created. This is when the crash happens.

Because PostView is on top of BlogView the BlogView is still active. Therefore when I insert a new object into core data that BlogView is showing it's having a fit.

I thought this might have been related to the cacheName for each fetchRequest but I ensured that these are indeed different and it did not resolve the issue in any case. Removing the predicate also did not help. Again, removing the sortDescriptor did fix the issue.

I've also tried deleting the cache after insert and that didn't solve it either. In fact I've also tried deleting the cache, setting the predicate again, setting the SortDescriptors again and then calling NSFetchedResultsController performFetch manually and the error occurs. However key to this is that I do NOT instantiate a new fetchedResultsController. I reuse the same one. Which should work.

It's as if I need to tell the first NSFetchedResultsController that changes are about to occur?

Upvotes: 0

Views: 39

Answers (1)

Etep
Etep

Reputation: 543

Ok I figured this one out. It was an odd one. I had to set BOTH the sortDescriptors and the Predicate to a different field within MyObject. For instance I could use an id field (or uuid) or name field. Something that you can compare. So for the predicate I set it to blog.uuid instead of just post and the same for the sortdescriptor.

What's odd for me is that just setting it for the SortDescriptor did not work. I had to change the descriptor. Yet I just wanted the posts for the blog so I'm not sure why I had to use the uuid (I guess I could've used the objectID too). Why not just using the object itself didn't work I'm unsure. It works when initially displayed and has for other objects. I think this is some sort of unique case for when using sortdescriptors and predicates with an insert (I assume an updated would've had the same issue).

Hope this helps anyone else in the future.

Upvotes: 0

Related Questions