请耐心等待,这需要一些解释。我有一个类似于下面的函数。
上下文:“aProject”是一个名为 LPProject 的核心数据实体,其数组名为“memberFiles”,其中包含另一个名为 LPFile 的核心数据实体的实例。每个 LPFile 代表磁盘上的一个文件,我们想要做的是打开每个文件并解析其文本,查找指向其他文件的 @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");
永远不会出现并且应用程序挂起。但是,(这就是事情变得非常奇怪的地方)——如果我先在小项目上运行代码,然后在大项目上运行它,一切都会完美运行。只有当我首先在大型项目上运行代码时,问题才会出现。
如果我将第二个调度行更改为:
dispatch_async(dispatch_get_main_queue(), ^{
(也就是说,使用async
代替sync
将块分派到主队列),一切都一直有效。完美。无论项目中有多少文件!
我无法解释这种行为。任何有关下一步测试内容的帮助或提示将不胜感激。