簡體   English   中英

使用子NSPrivateQueueConcurrencyType上下文保存Coredata Fetched Results Controller保存

[英]Coredata Fetched Results Controller save with child NSPrivateQueueConcurrencyType context

我有帶有<NSFetchedResultsControllerDelegate> UICollectionViewController <NSFetchedResultsControllerDelegate>CoreData Singleton管理器的CoreData 因此,當我嘗試更新對象的某些標題時,會看到錯誤。

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:

[錯誤]錯誤:嚴重的應用程序錯誤。 在核心數據更改處理期間捕獲到異常。 這通常是NSManagedObjectContextObjectsDidChangeNotification的觀察者內部的錯誤。 ALL或ANY運算符的左側必須是NSArray或NSSet。 與userInfo(空)一起使用CoreData:錯誤:嚴重的應用程序錯誤。 在核心數據更改處理期間捕獲到異常。 這通常是NSManagedObjectContextObjectsDidChangeNotification的觀察者內部的錯誤。 ALL或ANY運算符的左側必須是NSArray或NSSet。 與userInfo(null)2018-03-21 17:07:42.644646 + 0400 AppName [17860:3506816] ***由於未捕獲的異常'NSInvalidArgumentException'而終止應用程序,原因:'ALL或ANY運算符的左側必須可以是NSArray或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;
}

所以,我做錯了什么?

代碼刪除對象,工作正常:

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

因此,問題在於NSFetchedResultsController謂詞。 當某些內容更新時, NSFetchedResultsController准備重新加載集合視圖,並且在調用此方法之前:

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

它已崩潰,但從未顯示錯誤。 謝謝大家!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM