Отладка блокировки NSOperationQueue

Мне нужно руководство по отладке проблем с параллелизмом в Cocoa до 10.6. Я конвертирую цикл for для использования NSOperations, но в большинстве случаев код просто зависает в какой-то момент цикла. Я вижу вывод NSLog в консоли на этот счет. В редких случаях код будет выполняться полностью, и это нормально.

Код относится только к уровню модели и инициируется из метода в контроллере. Метод перебирает всего 8-10 объектов модели, указывая каждому из них записывать свои выходные данные в файл с уникальным именем. 8 объектов модели = 8 отдельных файлов. Нет вызовов графического интерфейса пользователя, а объекты модели являются подклассами NSManagedObject, которые содержат набор дочерних объектов NSManagedObject (0..n из них), которые каждый объект-владелец суммирует и записывает. Выходной формат — JSON.

Код:

__block NSMutableArray *collectionOfCourses = [[NSMutableArray alloc] initWithCapacity:[[self courses] count]];

/* Create a filename.  Use our title and set it to lowercase */
NSURL *ourFileURL = [aURL URLByAppendingPathComponent:[[self title] lowercaseString]];
ourFileURL = [ourFileURL URLByAppendingPathExtension:@"js"];

for (Course *aCourse in [self courses]) {
       [[self opQueue] addOperationWithBlock:^{
       NSArray *arrayForOneCourse = [aCourse arrayAndWriteToFileURL:aURL fileFormat:format];
   [collectionOfCourses addObject:arrayForOneCourse];
    }];
}

Я делаю много NSLogs, это может быть проблемой? Является ли NSLoging из фоновых потоков плохой вещью?

Поскольку я добавляю изменяемый массив из блока, правильно ли я объявляю изменяемый массив как __block? Я пробовал это обоими способами и, похоже, никакой разницы в отношении этой проблемы с зависанием.

Как отладить эту проблему с помощью Xcode v4? Я хочу знать строку кода, на которой он зависает, или какие две строки кода выполняются одновременно и вызывают блокировку выполнения. Мои прежние методы установки одной точки останова и пошагового выполнения кода больше не работают. , из-за параллелизма.

Спасибо


person Woodster    schedule 16.03.2011    source источник


Ответы (1)


Это не имеет ничего общего с вашей блочной переменной. Ваша проблема в том, что ни NSMutableArray, ни NSManagedObject никоим образом не формируют и не формируют потокобезопасность. Ты не можешь делать то, что делаешь здесь. Если вы хотите, чтобы это обрабатывалось вне основного потока, вам нужно использовать очередь отправки или что-то подобное для последовательной обработки каждого элемента (и даже когда вы вернетесь в основной поток, вы должны использовать ту же очередь, прежде чем читать из ваш изменяемый массив. Однако, вероятно, было бы проще и безопаснее сделать что-то вроде копирования изменяемого массива в неизменяемую версию, когда вы закончите, а затем отправить уведомление или обратный вызов в основной поток с новым неизменяемым скопировать встроенный.

person Jason Coco    schedule 16.03.2011
comment
Переработан и опубликован дополнительный вопрос в виде новой статьи. stackoverflow.com/questions/5363312/ - person Woodster; 19.03.2011