Why does an NSFetchedResultsController execute a Fetch: crash when recreating an NSFetchedResultsController with an equivalent NSFetchRequest?

Why [NSFetchedResultsController performFetch:] crash when recreating an NSFetchedResultsController with an equivalent NSFetchRequest ?

I have an application that has a table view controller for streams (message streams). When you click on a stream, it loads another table view controller, which uses the NSFetchedResultsController, to get all the messages from that stream and display them. I use NSFetchedResultsController because I can load messages in the background / delete / add new ones, and not worry about displaying them.

The second table view controller is used for all threads, so when I go back and then touch another thread, I just delete the current NSFetchedResultsController and set up a new one for the new thread.

The following are the steps to play CRASH:

  • Click on the stream to display me messages.
  • Reload the messages, so NSFetchedResultsController will be used to display new messages.
  • Go back.
  • Click another thread.
  • Go back.
  • Click the first line.

Clicking on NSFetchedResultsController creates one that is identical to the first. (The same cache and all). Instead of working as if it were throwing this error and failing:

Program received signal: "EXC_BAD_ACCESS".

NSFetchedResultsController sends a message to the freed object.

Here is the stack trace:

 #0 0x95ffd688 in objc_msgSend #1 0x0060699b in -[NSFetchedResultsController(PrivateMethods) _computeSectionInfo:error:] #2 0x00601bf0 in -[NSFetchedResultsController performFetch:] #3 0x0001c170 in -[CMNewMessagesViewController loadMessagesViewControllerForThread:showProfile:] at CMNewMessagesViewController.m:331 

3 is my method

Any ideas whatsoever? Any help would be greatly appreciated.


DECIDE!

That was my fault. I used sectionNameKeyPath, which was obtained from a different key value. This is normal as long as NSFetchRequest is sorted by this key value. The problem was that it was dynamically generated, since I did not want to waste space on the database for it. I used an instance variable in the NSManagedObject class that was cleared by didTurnIntoFault.

Now I think that the instance variable should have been created and then discarded and then recreated at some point, causing the NSFetchedResultsController sort to stop the markup.

This explains why the sectionNameKeyPath or delegate problem is not resolved.

Now I switched to the saved key value in the CoreData object and it seems to work fine.

+4
source share
2 answers

That was my fault. I used sectionNameKeyPath, which was obtained from a different key value. This is normal as long as NSFetchRequest is sorted by this key value. The problem was that it was dynamically generated, since I did not want to waste space on the database for it. I used an instance variable in the NSManagedObject class that was cleared by didTurnIntoFault.

Now I think that the instance variable should have been created and then discarded and then recreated at some point, which will cause the NSFetchedResultsController to sort before the markup stops.

This explains why the sectionNameKeyPath or delegate problem is not resolved.

Now I switched to the saved key value in the CoreData object and it seems to work fine.

0
source

When I call the executeFetch function, I received the same EXC_BAD_ACCESS signal in the system stack. Changes in the cache or something did not help.

 - (void)viewDidLoad { [super viewDidLoad]; MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate]; managedContext = [appDelegate managedObjectContext]; NSError *error = nil; NSFetchedResultsController *frC = self.fetchedResultsController; if (![frC performFetch:&error]) { /* */ } } 

Recently, I have found one small snippet that needs to be added. Actually, the problem was how I used iOS memory management (or not used).

 - (NSFetchedResultsController *)fetchedResultsController { if (fetchedResultsController != nil) { return fetchedResultsController; } NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Asiakasrekisteri" inManagedObjectContext:managedContext]; [fetchRequest setEntity:entity]; [fetchRequest setFetchBatchSize:200]; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"yritys" ascending:YES]; NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; [fetchRequest setSortDescriptors:sortDescriptors]; NSFetchedResultsController *aFetchedResultsController = [[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedContext sectionNameKeyPath:nil cacheName:nil] retain]; aFetchedResultsController.delegate = self; self.fetchedResultsController = aFetchedResultsController; [aFetchedResultsController release]; [fetchRequest release]; [sortDescriptor release]; [sortDescriptors release]; return fetchedResultsController; } 

aFetchedResultsController did have a very short independent life, but it was freed before executing Fetch. A save helped and got control.

+1
source

All Articles