djcj
djcj

Reputation: 149

NSmanaged context threads

I use a singleton for working with arrays etc. cross the views in the application.

To initialize the singleton and the NSManagedObjectContext, so that I can fetch objects, I use:

+(DataControllerSingleton *)singleDataController
{    
    static DataControllerSingleton * single=nil;

    @synchronized(self)
    {
        if(!single)
        {
            single = [[DataControllerSingleton alloc] init];            
            NSManagedObjectContext *context = [single.fetchedResultsController managedObjectContext];

            single.masterCareList = [[NSMutableArray alloc] init];
        }        
    }
    return single;
}

When I insert a new object that object will not show up in display functions until I restart the application. I insert new object through this method in the singleton class:

- (void)insertNewObject:(Care *)care
{
  NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];      

  NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];

  NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:  
   [entity name] inManagedObjectContext:self.managedObjectContext];

  NSString *fileName = care.pictureURL;
  NSString *text = care.causeText;
  NSDate  *date = care.date;
  NSData  *imgData = care.imageData;

  [newManagedObject setValue:fileName forKey:@"urlPath"];
  [newManagedObject setValue:text forKey:@"name"];
  [newManagedObject setValue:date forKey:@"date"];
  [newManagedObject setValue:imgData forKey:@"imageData"];

   // Save the context.
  [self saveContext];

  NSError *error = nil;
  if (![context save:&error]) {
      // Replace this implementation with code to handle the error appropriately.
      // abort() causes the application to generate a crash log and terminate. You should       
      not use this function in a shipping application, although it may be useful during 
         development.
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
      abort();
  }
}

My count method is the way I can tell that the new object is not included until I restart the application. The count method is also in the singleton as well.

- (NSUInteger)countOfList
{        
    NSArray *fetchedData = [_fetchedResultsController fetchedObjects];
    return [fetchedData count];   
}

When calling singleton I use:

DataControllerSingleton *singletonData = [DataControllerSingleton singleDataController];    
[singletonData insertNewObject:care];

managedObjectContext property:

.h:

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;

.m:

@implementation DataControllerSingleton

@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;

Why will not my new object show up in ex count until I restart application?

Am I somehow using different threads with different contexts, or different fethedResultsController or different singleton (shouldnt be possible right?)??


I added these two lines, which are not included in the genereated CoreData Stack, and it now works fine.

In singleton header:

@interface DataControllerSingleton : NSObject <NSFetchedResultsControllerDelegate>

In implementation file,

(NSFetchedResultsController *)fetchedResultsController {

    _fetchedResultsController.delegate = self;

Upvotes: 1

Views: 274

Answers (1)

Lorenzo B
Lorenzo B

Reputation: 33428

As I understand from your question, you are using a table or similar.

If you want to update the table as soon as you save the context you need to:

  1. Reload the data table [table reloadData];
  2. or implement in the correct delegate methods of (take a look to How To Use NSFetchedResultsController)

If you follow the first option, you can just do a save in the context and call realod data on the table.

NSError *error = nil;
if (![context save:&error]) {
  // Replace this implementation with code to handle the error appropriately.
  // abort() causes the application to generate a crash log and terminate. You should       
  //not use this function in a shipping application, although it may be useful during 
         development.
  NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
  abort();
}

[table reloadData];

NOTE THAT YOU ARE CALLING THE SAVE TWICE Do it once. In this case I suppose that [self saveContext]; does the saving as above.

If you follow the second approach, the data reload woul be handled for you.

Hope that helps.

Edit

The delegate of your fetched results controller should be a view controller (the one that contains the table). Do not put it in your singleton!!

Upvotes: 1

Related Questions