Peter
Peter

Reputation: 65

Coredata Fetched Results Controller save with child NSPrivateQueueConcurrencyType context

I have UICollectionViewController with <NSFetchedResultsControllerDelegate> and CoreData Singleton manager. So when I trying to update some Title of my object I see error.

CollectionViewController.m

@interface CollectionViewController ()<NSFetchedResultsControllerDelegate>

@property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;
@property (strong, nonatomic) NSManagedObjectContext* managedObjectContext;

@implementation CollectionViewController

- (NSManagedObjectContext*) managedObjectContext {
    if (!_managedObjectContext) {
        _managedObjectContext = [[CoreDataManager sharedManager] managedObjectContext];
    }
    return _managedObjectContext;
}

-(void)pushTheButton: (UIButton*) sender{
    NSIndexPath *indexPath = [self.collectionView indexPathForCell:(PKMapObjectCVCell *)sender.superview.superview];
    SomeObjectClass* object = [self.fetchedResultsController objectAtIndexPath:indexPath];
    [[CoreDataManager sharedManager] changeValueForObject: object.objectID];
}

CoreDataManager.m

@implementation CoreDataManager

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

+(CoreDataManager*) sharedManager{
    static CoreDataManager* manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[CoreDataManager alloc] init];
    });
    return manager;
}

- (void) changeValueForObject:(NSManagedObjectID*) myobjectID{
    NSManagedObjectContext * bgcontext = [self getContextForBGTask];
    SomeObjectClass * editableObject = [bgcontext objectWithID:myObjectID];
    editableObject.title = @"New Title";

//    [bgcontext updatedObjects];
    [self saveContextForBGTask:bgcontext];

}

- (void)saveContextForBGTask:(NSManagedObjectContext *)bgTaskContext {
    if (bgTaskContext.hasChanges) {
         [bgTaskContext performBlockAndWait:^{ //error on this line:

[error] error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. The left hand side for an ALL or ANY operator must be either an NSArray or an NSSet. with userInfo (null) CoreData: error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. The left hand side for an ALL or ANY operator must be either an NSArray or an NSSet. with userInfo (null) 2018-03-21 17:07:42.644646+0400 AppName[17860:3506816] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'The left hand side for an ALL or ANY operator must be either an NSArray or an NSSet.

            NSError *error = nil;
            [bgTaskContext save:&error];
        }];
        [self saveDefaultContext:YES]; // Save default context
    }
}
- (NSManagedObjectContext *)managedObjectContext {
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];

    _mainPrivateManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [_mainPrivateManagedObjectContext setPersistentStoreCoordinator:coordinator];

    _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    [_managedObjectContext setParentContext:_mainPrivateManagedObjectContext];
    return _managedObjectContext;
}

- (NSManagedObjectContext *)getContextForBGTask {
    NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [context setParentContext:_managedObjectContext];
    return context;
}

So, what I am doing wrong?

code delete object, is working fine:

 - (void) switchObjectLike:(NSManagedObjectID*) mapObjectID{
    NSManagedObjectContext * bgcontext = [self getContextForBGTask];
    PKMapObj * mapObject = [bgcontext objectWithID:mapObjectID];
    [bgcontext deleteObject:mapObject];
    [self saveContextForBGTask:bgcontext];
}

Upvotes: 0

Views: 65

Answers (1)

Peter
Peter

Reputation: 65

So, problem was with predicate in NSFetchedResultsController. When some content was updated, NSFetchedResultsController preparing to reload collection view, and before call this method:

-(void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
      atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
     newIndexPath:(NSIndexPath *)newIndexPath

it was crashed, but never shown error with it. Thanks everybody!

Upvotes: 0

Related Questions