1

如何为已创建的 UIManagedDocument 创建 managedObjectContext 并将其与全局调度队列相关联?或者创建 managedObjectContext 的正确方法是什么。

信息:我正在以最原始的方式处理我的 managedObjectContext,只是通过与 managedDocument 一起创建它_managedDocument = [[UIManagedDocument alloc] initWithFileURL:url];

但是,这会将 managedObjectContext 与我想避免的主队列相关联,并将其与该队列相关联。

_backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);

正确的做法是什么?

4

1 回答 1

2

好的,解决了,确切的答案:

Core Data 要求每个队列操作自己独立的managedObjectContext,它是在它所属的队列上创建的。当在 this 上获取数据时managedObjectContext,它将被合并到主队列的托管对象上下文中。要创建背景managedObjectContext,请为其指定与主队列相同的 Persistent Store Coordinator managedObjectContext。使用此通知,当后台托管对象上下文保存时,更改将发送到主队列并合并。

然后执行获取的好方法是在内部进行performBlock:,以确保您在正确的队列中获取。

[_backgroundManagedObjectContext performBlock:^{
       // fetch here
    }];

完整清单:

@implementation databaseManager {
    UIManagedDocument* _databaseManagedDocument;

    NSManagedObjectContext* _backgroundManagedObjectContext;
    dispatch_queue_t _backgroundContentFetchingQueue;

}

- (id)init
{
    self = [super init];
    if (self) {

        NSURL* url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
        url = [url URLByAppendingPathComponent:@"database"];

        _databaseManagedDocument = [[UIManagedDocument alloc] initWithFileURL:url];
        _backgroundContentFetchingQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);

        [self openManagedDocument];  
    }

    return self;
}

- (void)initializeBackgroundManagedObjectContext
{
    dispatch_async(_backgroundContentFetchingQueue, ^{

        NSPersistentStoreCoordinator *coordinator = _databaseManagedDocument.managedObjectContext.persistentStoreCoordinator;
        if (!coordinator) {
            // Error if we don't have a coordinator.
            return;
        }

        // Create the Background Managed Object Context
        _backgroundManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
        [_backgroundManagedObjectContext setPersistentStoreCoordinator:coordinator];
        [_backgroundManagedObjectContext setUndoManager:nil];

        // Notify the main queue of changes the background queue makes
        [[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification
                                                          object:_backgroundManagedObjectContext
                                                           queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
                                                               dispatch_async(dispatch_get_main_queue(), ^{
                                                                   [_databaseManagedDocument.managedObjectContext mergeChangesFromContextDidSaveNotification:note];
                                                               });
                                                           }];
    });

}

- (void)openManagedDocument
{
    if (!([[NSFileManager defaultManager] fileExistsAtPath:[_databaseManagedDocument.fileURL path]])){
        [_databaseManagedDocument saveToURL:_databaseManagedDocument.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success){
            if (success) {
                [self initializeBackgroundManagedObjectContext];
            } else NSLog(@"Database document creation error");
        }];
    } else if (_databaseManagedDocument.documentState == UIDocumentStateClosed) {
        [_databaseManagedDocument openWithCompletionHandler:^(BOOL success){
            if (success) {
                [self initializeBackgroundManagedObjectContext];
            } else NSLog(@"Database document opening error");
        }];

    } else if (_databaseManagedDocument.documentState == UIDocumentStateNormal) {

        [self initializeBackgroundManagedObjectContext];
    }
}

- (void)dealloc
{
    dispatch_release(_backgroundContentFetchingQueue);
}

@end

希望我没有错过任何东西。原帖在这里:POST

于 2013-08-02T06:58:32.837 回答