在Core Data中导入大型数据集时更新UI

时间:2014-08-24 08:34:50

标签: ios objective-c multithreading user-interface core-data

在我的应用程序中,我有一个功能,可以将大型数据集从服务器下载到Core Data中。它看起来像这样:

for (PFObject *historyObject in historyArray) {
    History *history = (History *)[NSEntityDescription insertNewObjectForEntityForName:@"History" inManagedObjectContext:managedObjectContext];
    history.date = historyObject.date;
    // ...
}

因为这可能需要几分钟,我想在流程中更新UI并向用户显示已经完成的进度。 现在因为将此数据插入Core Data会阻塞主线程,我不确定是否有其他正确的方法来更新UI。

我已经尝试了几种将插入移动到不同线程的方法,但是Core Date响应时总是遇到问题。

我希望那里的人有个好主意,想分享。 非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

我目前通过使用并发类型NSPrivateQueueConcurrencyType初始化ManagedObjectContext并将父上下文设置为主ManagedObjectContext来解决此问题。 对于任何有同样问题的人:

- (void)doSomething
{
    _backgroundMOC = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [_backgroundMOC setParentContext:[kDelegate managedObjectContext]];

    for (int i = 0; i < [cars count]; i++)
    {
        [_backgroundMOC performBlockAndWait:^{

            Drive *drive = (Drive *)[NSEntityDescription insertNewObjectForEntityForName:@"Drive" inManagedObjectContext:_backgroundMOC.parentContext];

            ....do more stuff...

        }];
    }

    [self performSelectorOnMainThread:@selector(showProgress:) withObject:[NSNumber numberWithFloat:((float)i/(float)[cars count])] waitUntilDone:NO];
}

要使其工作,您必须更改AppDelegate中的managedObjectContext:

- (NSManagedObjectContext *)managedObjectContext
{
    if (_managedObjectContext != nil) 
    {
    return _managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) 
    {
        _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
        [_managedObjectContext setPersistentStoreCoordinator:coordinator];

    }

    return _managedObjectContext;
}