Потерпи меня, это займет некоторое объяснение.У меня есть функция, похожая на приведенную ниже.
Контекст: «aProject» - это объект Core Data с именем LPProject с массивом с именем «memberFiles», который содержит экземпляры другого объекта Core Data с именем 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
}
}
}
Теперь вот, где все становится странным:
Этот код работает, но я вижу странную проблему.Если я запускаю его на LPProject, который имеет несколько файлов (около 20), он работает отлично.Однако, если я запускаю его на LPProject, который имеет больше файлов (скажем, 60-70), он NOT работает правильно.Мы никогда не возвращаемся к основному потоку, NSLog(@"got to main thread");
никогда не появляется и приложение зависает.НО, (и это то, где вещи становятся действительно странными) - если я запускаю код для небольшого проекта ПЕРВЫМ, а затем запускаю его для большого проекта, все работает отлично.Проблема возникает только тогда, когда я сначала запускаю код в большом проекте.
А вот кикер, если я изменю вторую строку отправки на эту:
dispatch_async(dispatch_get_main_queue(), ^{
(Этоиспользуйте async
вместо sync
для отправки блока в основную очередь), все работает все время.В совершенстве.Независимо от количества файлов в проекте!
Я затрудняюсь объяснить это поведение.Буду признателен за любую помощь или советы о том, что проверить дальше.