忍受着我,这是要做一些解释。我有一个如下所示的函数。dispatch_sync与主队列上的dispatch_async
上下文:“aProject”是名为LPProject的核心数据实体,其数组名为“memberFiles”,其中包含另一个名为LPFile的Core Data实体的实例。每个LPFile代表磁盘上的一个文件,我们想要做的就是打开这些文件并解析它的文本,寻找指向OTHER文件的@import语句。如果我们找到@import语句,我们希望找到它们指向的文件,然后通过向表示第一个文件的核心数据实体添加关系,将该文件“链接”到该文件。由于所有这些都可能需要一些时间处理大文件,我们将使用GCD从主线程中删除它。
- (void) establishImportLinksForFilesInProject:(LPProject *)aProject {
dispatch_queue_t taskQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (LPFile *fileToCheck in aProject.memberFiles) {
if (//Some condition is met) {
dispatch_async(taskQ, ^{
// Here, we do the scanning for @import statements.
// When we find a valid one, we put the whole path to the imported file into an array called 'verifiedImports'.
// go back to the main thread and update the model (Core Data is not thread-safe.)
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"Got to main thread.");
for (NSString *import in verifiedImports) {
// Add the relationship to Core Data LPFile entity.
}
});//end block
});//end block
}
}
}
现在,这里的事情变得怪异:
此代码的工作,但我看到一个奇怪的问题。如果我在有几个文件(大约20个)的LPProject上运行它,它可以完美运行。但是,如果我在具有更多文件(例如60-70)的LPProject上运行它,它确实运行正确NOT。我们永远不会回到主线程,NSLog(@"got to main thread");
从不出现,应用程序挂起。但是,(这是真正奇怪的地方)---如果我在小型项目FIRST上运行代码然后在大型项目上运行代码,那么一切都很完美。只有当我在大型项目上运行代码时,才会出现问题。
而这里的踢球,如果我改变第二派遣线到这一点:
dispatch_async(dispatch_get_main_queue(), ^{
(也就是说,使用async
代替sync
到块分派到主队列),一切正常,所有的时间。完美。无论项目中有多少文件!
我无法解释这种行为。任何帮助或提示下一步测试将不胜感激。
注意:为了简洁起见,我已经编写了“扫描”和“核心数据条目”代码片段。但是,我几乎肯定他们不是罪魁祸首,因为如果我将所有内容放在单个线程中,并且他们在上述多线程情况下完美工作(通过首先运行一个小型项目“预热”所有内容和/或在主队列上使用dispatch_async()而不是dispatch_sync())。 – Bryan
听起来就像是碰到了一个死锁问题 –
当你处于这种状态时,你应该对你的应用程序运行示例或工具来查看其他线程都在做什么。如果他们陷入僵局,发生的事情应该更加明显。 –