使用NSPrivateQueueConcurrencyType的具体/完整示例?

时间:2013-10-03 05:39:55

标签: ios uitableview core-data grand-central-dispatch

我还在编写我的RSS阅读器,我已经达到了这样的程度,我希望通过最新帖子立即填充我的Feeds,让事情变得更顺畅。

问题是它使用以下消息严重崩溃我的应用程序:

2013-10-02 21:06:25.474 uRSS[97209:a0b] *** Terminating app due to uncaught 
exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource 
must return a cell from tableView:cellForRowAtIndexPath:'

(堆栈跟踪)

我得出的结论是我没有在这里运行线程安全,然后我发现了this kind of CoreData snippets

//Core Data's NSPrivateQueueConcurrencyType and sharing objects between threads
[context performBlock:^{
    // fetch request code

    NSArray *results = [context executeFetchRequest:request error:nil];

    dispatch_async(dispatch_get_main_queue(), ^(void) {
        Class *firstObject = [results objectAtIndex:0];
        // do something with firstObject
    });
}];

// Assume we have these two context (They need to be set up. Assume they are.)
NSManagedObjectContext *mainMOC = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType] autorelease];
NSManagedObjectContext *backgroundMOC = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType] autorelease];

// Now this can safely be called from ANY thread:
[backgroundMOC performBlock:^{
    NSArray *results = [context executeFetchRequest:request error:nil];
    for (NSManagedObject *mo in results) {
        NSManagedObjectID *moid = [mo objectID];
        [mainMOC performBlock:^{
                NSManagedObject *mainMO = [mainMOC objectWithID:moid];
            // Do stuff with 'mainMO'. Be careful NOT to use 'mo'.
        }];
    }
}];

现在,我想知道的是:

  • 应该将backgroundMOC定义为类成员属性,还是每次调用使用它的方法?
  • 如果这个方法本身是异步调用的(RSS解析方法是动态创建对象的话)该怎么办?
  • 我如何安全地通知我的UITAbleView我的MOC已经更新,以便它可以刷新而不会崩溃?
  • 这仅适用于抓取,还适用于插入,删除等对象?
  • 我在哪里可以找到成功应用此概念的工作示例?

1 个答案:

答案 0 :(得分:1)

1)backgroundMOC应该在您使用它的范围内定义。比如,如果您使用SomeClass内的上下文,最好将其定义为SomeClass的属性。但是,通常很多类共享相同的上下文(例如,在所有viewControllers之间共享mainMOC是完全可以的)所以我建议在AppDelegate或其他一些单例中定义mainMOCbackgroundMOC
2)没关系。但是,每次创建上下文都是个坏主意 - 参见1并以单例形式初始化它们 3)看看NSFetchedResultsController。这正是您设置tableView和跟踪CoreData更改所需的内容 4)是的 5)不能真正指出你的工作实例。在developer.apple.com =)

上找到一些东西

同时备注:
1)您的班级不能被命名为班级 2)使用existingObjectWithID:error:,而不是objectWithID: - 检查this回答,这在我的经历中真的很烦人 3)阅读NSManagedObjectContext concurrency模式