Ios 使用NSPrivateQueueConcurrencyType的具体/完整示例?
我还在编写我的RSS阅读器,我已经到了一个地步,我希望通过立即用最新的帖子填充我的提要来让事情变得更顺利 问题是它会严重破坏我的应用程序,并显示以下消息:Ios 使用NSPrivateQueueConcurrencyType的具体/完整示例?,ios,uitableview,core-data,grand-central-dispatch,Ios,Uitableview,Core Data,Grand Central Dispatch,我还在编写我的RSS阅读器,我已经到了一个地步,我希望通过立即用最新的帖子填充我的提要来让事情变得更顺利 问题是它会严重破坏我的应用程序,并显示以下消息: 2013-10-02 21:06:25.474 uRSS[97209:a0b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a ce
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)
我得出结论,我在这里运行线程不安全,然后我发现:
现在,我想知道的是:
- backgroundMOC应该定义为类成员属性,还是每次调用使用它的方法时都应该定义
- 如果该方法本身是异步调用的(RSS解析方法会动态创建对象),该怎么办
- 我如何安全地通知UITAbleView我的MOC已更新,以便它可以刷新而不会崩溃
- 这只适用于抓取,还是也适用于对象插入、删除等
- 在哪里可以找到成功应用此概念的工作示例
- 1)背景MOC应在您使用它的范围内定义。比如说,如果在
SomeClass
中使用上下文,最好将其定义为SomeClass
的属性。但是,通常许多类共享相同的上下文(例如,在所有ViewController之间共享mainMOC
是可以的),因此我建议在AppDelegate或其他单例中定义mainMOC
和backgroundMOC
。2) 没关系。但是,每次创建上下文都是个坏主意——请参见1,并在singleton中初始化它们一次。
3) 看一看。这正是设置tableView和跟踪CoreData更改所需的功能。
4) 是
5) 无法真正向您指出工作示例。在developer.apple.com=)上查找相关信息 另请注意:
1) 您的类不能命名为class
2) 使用
existingObjectWithID:error:
,而不是objectWithID:
-检查答案,根据我的经验,这确实是一个令人讨厌的问题3) 阅读有关模式的内容
非常感谢您的回答。因此,如果我用async_分派多对象创建的方法创建backgroundMOC,然后将其作为参数传递给这个函数,这就可以了,或者更糟?自动取款机,当我试图打开一个桌子部分时,它崩溃了…我认为这很糟糕。如果您将
backgroundMOC
和mainMOC
作为appDelegate的属性,您将永远不会考虑是否可以在某个地方传递它们。对于backgroundMOC
来说,最好不要dispatch\u async
,而是backgroundMOC performBlock:
作为代码片段中的一部分<代码>背景MOC performBlock:-在区块内完成所有工作。如果插入/删除/更新了某些内容-保存上下文。但是,要获取和显示某些内容,您必须使用mainMOC.Re-谢谢!如何将mainMOC与更新的backgroundMOC同步?我的问题是,我异步获取多个RSS提要,并希望在后台线程中插入新找到的帖子,同时在每次创建新对象时通知我的GUI,以便我可以看到计数器增加…-使用“通知”部分跟踪其他线程中的更改。通常,您必须使用它的第一个模式。比方说-在appDelegate中创建上下文,您订阅了NSManagedObjectContextDidSaveNotification
。在通知处理程序中,您只需[mainMOC mergeChangesFromContextDidSaveNotification:notification]
即可!如果您有NSFetchedResultsController设置,它将已经跟踪更改,因为mainMOC
将在合并期间更改。明白了吗?但是,如果您需要某种其他类型的交互(没有NSFetchedResultsController),您可以从NSManagedObjectContextDidSaveNotification
处理程序中向ViewController发送用户定义的通知。
//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'.
}];
}
}];