3

I'm still coding my RSS reader and I have gotten to the point where I'd like things to go smoother by background filling my Feeds at once with the newest Posts.

The problem is that it crashes my app quite badly with messages such as:

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:'

(stacktrace)

I came to the conclusion that I am not running thread safe here and I then discovered 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'.
        }];
    }
}];

Now, what I would like to know is the following:

  • should the backgroundMOC be defined as a Class member property, or everytime the method that uses it is invoked?
  • what if this method is itself invoked asynchronously (the RSS parsing method create the objects on the fly)?
  • How may I securely notify my UITAbleView that my MOC's been updated so that it can refresh without crashing?
  • Does this only apply to fetches, or also to objects insertions, deletions, etc?
  • Where could I find a working example of this concept successfully applied?
4

1 回答 1

1

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



另请注意:
1)您的类不能命名为 Class
2)使用existingObjectWithID:error:,不是objectWithID:- 检查这个答案,这在我的经验中真的很烦人
3)阅读NSManagedObjectContext 并发模式

于 2013-10-03T06:52:19.710 回答