8

I'm experiencing a weird behavior when using a secondary thread to refresh NSFetchedResultsController contents and I'd like to know it this is a common issue or I might be doing something wrong.

I've got a centralized NSManagedObjectContext residing in my main delegate object which is used and shared by all view controllers. After loading a table by executing a fetch and calling its delegate method, a secondary thread is launched in background to update its results. However, and only in strange occasions, when inserting new entries they get duplicated in the table view. If I exit and reenter, duplicated rows disappear, what makes think they've only have existed in the managed object context.

These are the followed steps:

  1. A background NSOperation thread creates a confined context linked to the same persistent store of the main application delegate.
  2. The new thread starts listening NSManagedObjectContextDidSaveNotification notifications.
  3. New rows are deleted, updated or inserted into the secondary context making always a save call when reaching some batch size.
  4. When saving in the background, the notification method calls the centralized context mergeChangesFromContextDidSaveNotification selector on the main thread as follow.

    -(void)mergeChanges:(NSNotification *)notification
    {
        NSManagedObjectContext *mainContext = [[appDelegate sharedDelegate] managedObjectContext];
    
        [mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) 
                                      withObject:notification 
                                   waitUntilDone:NO];
    }
    
  5. After finishing the operation the listener is removed and the secondary context released.

Does anybody have idea what is the reason is causing my table view rows to get duplicated, and how it can be solved?

Thanks in advance for your help.

MPelletier
  • 16,256
  • 15
  • 86
  • 137
  • Why are you making changes in the background context? Do the changes arise from a download or do they arise from user input? Do you create a new context for every single change or use one background context for all changes. – TechZen Jun 08 '11 at 14:15
  • are you using cache? if yes try to not use it. This issue could be cause by strong references to objects also. Or you might have 2 contexts and they are not in sync, im also having this issue. My problem is with wrong context thread utilisation. Try performBlock in the context while saving in the background. – João Nunes Feb 13 '13 at 11:36

1 Answers1

1

You can't actually have "duplicated" objects in a managed object context because every object in a context must be unique. Maintaining unique objects is the core function of a context so it just doesn't happen. So, you have one of two condtions:

  1. You are creating two or more managed objects with the same attributes such that they show up together when sorted into a tableview.
  2. Your tableview datasource logic is actually returning to the tableview the data from the same managed object twice in some circumstances. This would create the illusion that there is a duplicate managed object in the context.

I think the latter more likely.

TechZen
  • 64,370
  • 15
  • 118
  • 145
  • Strange, but this seems only to happen on iOS 3.0. I've reviewed the delegate and datasource methods and both are almost identical as in Apple examples. – Miguel Ángel Ortuño Jun 14 '11 at 11:01
  • 1
    "Almost identical" doesn't count in programming. Check the differences in both the delegate and datasource methods and the data model itself. I would suggest logging both the managed objects and the managed object context in `cellForRowAtIndexPath:` right before each cell is populated. That will tell you (1) which context you are actually using and (2) whether the duplicate rows arise from the same managed object or two managed objects with the same value. – TechZen Jun 14 '11 at 14:24
  • 1
    Circumstance two can happen in some cases due to lack of permanent object IDs... e.g. https://stackoverflow.com/a/44785491/1433553 – atlex2 Apr 16 '20 at 03:14