请耐心听我解释一下。我有一个函数,如下所示。
背景信息: "aProject"是一个名为LPProject的Core Data实体,其中包含一个名为'memberFiles'的数组,该数组包含另一个Core Data实体LPFile的实例。每个LPFile代表磁盘上的一个文件,我们想要做的是打开每个文件并解析其文本,查找指向其他文件的@import语句。如果我们找到了@import语句,我们希望定位它们指向的文件,然后通过将关系添加到表示第一个文件的Core Data实体来将该文件与此文件“链接”起来。由于所有这些都可能需要花费大量时间在大型文件上完成,因此我们将使用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上运行它,它就不能正确地运行。我们从未回到主线程,NSLog(@"got to main thread");
从未出现,应用程序挂起。但是,(这就是事情变得非常奇怪的地方)---如果我先在小项目上运行代码,然后再在大项目上运行它,一切都可以完美地工作。只有当我首先在大项目上运行代码时,才会出现问题。
这里的关键是,如果我将第二个分派行更改为以下内容:
dispatch_async(dispatch_get_main_queue(), ^{
也就是说,使用async
而不是sync
将块派发到主队列,无论项目中有多少个文件,都可以完美地工作。
我无法解释这种行为。希望您能提供帮助或提示下一步要测试什么。