Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 核心数据多线程和嵌套上下文_Multithreading_Core Data_Nsmanagedobjectcontext_Nsfetchedresultscontroller - Fatal编程技术网

Multithreading 核心数据多线程和嵌套上下文

Multithreading 核心数据多线程和嵌套上下文,multithreading,core-data,nsmanagedobjectcontext,nsfetchedresultscontroller,Multithreading,Core Data,Nsmanagedobjectcontext,Nsfetchedresultscontroller,我刚刚开始学习核心数据编程。我尝试制作一个示例,其中有一个表视图,显示人员列表(属性:名字、姓氏)。表视图依赖NSFetchResultController来显示人员列表 我遵循嵌套上下文模式,如下所示: 根上下文(NSPrivateQueueConcurrencyType)主上下文(NSMainQueueConcurrencyType)子上下文(NSPrivateQueueConcurrencyType) 子上下文用于执行巨大的插入/获取(使用perormBlock:method)。 当我尝试

我刚刚开始学习核心数据编程。我尝试制作一个示例,其中有一个表视图,显示人员列表(属性:名字、姓氏)。表视图依赖NSFetchResultController来显示人员列表

我遵循嵌套上下文模式,如下所示:

根上下文(NSPrivateQueueConcurrencyType)主上下文(NSMainQueueConcurrencyType)子上下文(NSPrivateQueueConcurrencyType)

子上下文用于执行巨大的插入/获取(使用perormBlock:method)。 当我尝试执行一个巨大的插入(大约5000行),先保存子上下文,然后保存主上下文,再保存根上下文时,我看到我的UI被阻塞,直到保存完成

有谁能告诉我,为了实现高性能的应用程序,最好的解决方案是什么?谁能给我提供一个简单的代码,演示如何在后台进行大量的获取/插入,而不阻塞UI

    [_indicator startAnimating];

NSManagedObjectContext *aContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
aContext.parentContext = [[SDCoreDataController sharedInstance] mainManagedObjectContext];

[aContext performBlock:^{

    NSError *error;

    for (int i = 0; i < 5000; i++)
    {
        FootBallCoach *backgroundCoach = [NSEntityDescription insertNewObjectForEntityForName:@"FootBallCoach" inManagedObjectContext:aContext];

        backgroundCoach.firstName = [NSString stringWithFormat:@"José %i",i];
        backgroundCoach.lastName = [NSString stringWithFormat:@"Morinho %i",i];
        backgroundCoach.cin = [NSString stringWithFormat:@"%i",i];

        if (i % 50 == 0)
        {
            [aContext save:&error];

            [aContext reset];
        }
    }

    [[SDCoreDataController sharedInstance] saveMainContext];
    [[SDCoreDataController sharedInstance] saveRootContext];

    dispatch_async(dispatch_get_main_queue(), ^{

        [_indicator stopAnimating];

        [self refreshCoaches:nil];
    });

}];
[\u指示器启动激活];
NSManagedObjectContext*aContext=[[NSManagedObjectContext alloc]initWithConcurrencyType:NSPrivateQueueConcurrencyType];
aContext.parentContext=[[SDCoreDataController sharedInstance]mainManagedObjectContext];
[A文本执行锁:^{
n错误*错误;
对于(int i=0;i<5000;i++)
{
FootBallCoach*backgroundCoach=[NSEntityDescription insertNewObjectForEntityForName:@“FootBallCoach”inManagedObjectContext:aContext];
backgroundCoach.firstName=[NSString stringWithFormat:@“José%i”,i];
backgroundCoach.lastName=[NSString stringWithFormat:@“Morinho%i”,i];
backgroundCoach.cin=[NSString stringWithFormat:@“%i”,i];
如果(i%50==0)
{
[文本保存:&错误];
[文本重置];
}
}
[[SDCoreDataController sharedInstance]saveMainContext];
[[SDCoreDataController sharedInstance]saveRootContext];
dispatch\u async(dispatch\u get\u main\u queue()^{
[_指示器停止动画制作];
[自我更新教练:无];
});
}];
不要进行“大量”导入。
每次对存储执行写入操作时,
NSPersistentStoreCoordinator
都会锁定存储以执行任何其他类型的操作。因此,如果用户界面在此期间试图获取数据,它将被阻止。

将保存的对象分割为100~200个对象(取决于对象大小和复杂性)。
分段实际上取决于对象图结构,伪代码是:

编辑:我编辑了代码,以反映对保存过程的更正。
您保存到存储区(实际文件)的操作也应该分段,否则您仍然会执行“巨大”的保存操作。

for ( i = 0; i < LARGE_N; i += BATCHSIZE)
{
    @autoreleasepool {
        batchInfo = importInfos[i : MIN(i+BATCHSIZE-1,LARGE_N-1]; //array of the batch
        //use existing objects or create new ones if needed
        //use batch fetching to reduce existing items find time
        batchInfo = createOrReuseItemsForBatchInfo(batchInfo);
        //you can also practice weeding:
        //  create all items as newly inserted
        //  after batch insertion completed, find existing items, 
        //     replace them with the newly inserted and delete the duplicated inserted objects.
        //save all the way to the store
        NSManagedObjectContext* ctx = context;
        __block BOOL saveSuccessful = YES;
        while(ctx && saveSuccessful) {
            [ctx performBlockAndWait:^{
                saveSuccessful = [ctx save:&error]
            }];
            ctx = ctx.parentContext;
        }
        //handle unsuccessful save
        [context  reset];
        //You can discard processed objects from importInfos array if you like
    }
}
for(i=0;i
现在,我正在运行for循环,每次插入100个项目时都会保存。您确认嵌套上下文方法是最好的方法吗?当我的数据库第一次为空时,它可以正常工作。但是当我有大约20000个项目,并且我尝试插入5000个新项目时,UI会被阻止。如果保存100个项目,UI仍然会被阻止d尝试减少批处理大小。嵌套上下文体系结构在某些方面很好(根据我的经验,主要是小型导入和简单的存储操作)。如果您需要最大的并发性,您可以使用多协调器环境(但是您需要将更改合并到主上下文中,这本身就是一个故事).5K项插入总是很慢,因为写入操作会在操作系统级别阻止文件。正如我所说的,使用分段导入(最好在BG线程上花费更多时间并执行读取操作,然后太频繁和长时间地阻止UI)。我刚刚尝试了多协调器环境方法,得到了相同的结果。每次新的插入操作(5000项)我都会使用performBlock:方法创建一个单独的上下文,每次插入100项时我都会保存该方法。我的tableView(基于NSFetchResultController)仍处于阻塞状态。