Core Data 代码和多线程

Posted

技术标签:

【中文标题】Core Data 代码和多线程【英文标题】:Core Data code and multithreading 【发布时间】:2012-01-15 00:29:11 【问题描述】:

下面的代码是我的tableViewController的fetch data(第一次填充数据)部分。我正在使用 NSManagedDocument 的 managedObjectContext 来填充(预填充)我的数据库。源代码是我从 TXT 文件中清理的一个数组,它直接位于 Xcode 的资源文件夹中。创建完成后,我有文档案例,例如关闭/打开和正常。

以下代码使用获取的结果控制器请求正确输入并将我的数据提取到表中。但是,当数据加载到旨在将 UI 从这一一次性数据创建(26854 个对象名称)释放到 managedObject.name 属性繁重操作的线程中时,tableview 和我的 UI 被冻结(1-15 秒我认为是第一次为我的数据库填充 document.managedObjectContext 时)。

10-15 秒后数据加载并正确显示。但是,当我停止模拟器并在模拟器中重新启动应用程序时,虽然我保存了如下代码所示的文档,并且我使用相同的获取结果控制器设置(和请求)表视图显示为空,但在这种情况下它是可移动的(在这个阶段文档状态显示打开和正常,文件路径相同,我检查了......似乎既不是自动保存也不是显式 saveForOverwriting 我使用工作......或者是别的什么?我尝试了很多东西,我很快就会疯掉。我认为这与我的多线程有关。

self.managedObjectNames 是表格视图中的数组属性,我在表格视图的 loadView 期间从 TXT 文件中设置它:

有没有人可以在这里显示错误?是不是我在实体创建类的方法中给了self.managedObjectNames。

谢谢!

- (void)fetchDataIntoDocument:(UIManagedDocument *)document 

    dispatch_queue_t fetchQ = dispatch_queue_create("Data fetcher", NULL);
    dispatch_async(fetchQ, ^

            [document.managedObjectContext performBlock:^
                for (int i = 0; i < 26854; i++) 
                    [managedObject managedObjectWithId:[NSNumber numberWithInt:i] andArray:self.managedObjectNames inManagedObjectContext:document.managedObjectContext];
                
                // NSLog(@"Save baby!!?");
                [document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:nil];
            ];
    );
    dispatch_release(fetchQ);

【问题讨论】:

developer.apple.com/library/content/documentation/Cocoa/… 【参考方案1】:

你的 UI 被阻塞 10-15 秒的原因是因为 document.managedObjectContext 是用 NSMainQueueConcurrencyType 创建的。这意味着 performBlock: 方法将在主队列上执行。

在您的代码中创建 fetchQ 没有任何理由。如果获取数据需要相当长的时间但添加它们会很快(例如只创建/修改少数对象),那将是有原因的:

dispatch_async(fetchQ, ^

    // fetch data here (e.g. fetchAttribute may take few seconds)
    NSString *attribute = fetchAttribute();

    [document.managedObjectContext performBlock:^
        MyObject *o;
        o = [NSEntityDescription insertNewObjectForEntityForName:@"MyObject"
                                          inManagedObjectContext:document.managedObjectContext];
        o.myAttribute = attribute;
    ];
);

但是我不知道你的主要问题的答案。

【讨论】:

以上是关于Core Data 代码和多线程的主要内容,如果未能解决你的问题,请参考以下文章

多线程和多进程的区别

python 多进程和多线程配合

Python多线程和多进程谁更快?

EF 数据上下文 - 异步/等待和多线程

多线程和多进程通信原理

单线程和多线程处理1W条数据对比代码