Отладка NSOperationQueue Blocking - PullRequest
0 голосов
/ 16 марта 2011

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

Код только на уровне модели, инициируемый методом в контроллере. Метод перебирает всего 8-10 объектов модели, инструктируя их записывать каждый вывод в файл с уникальным именем. 8 объектов модели = 8 отдельных файлов. До GUI нет вызовов, и объектами модели являются подклассы 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, это будет проблемой? NSLog'ing из фоновых потоков - это плохо?

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

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

спасибо

1 Ответ

3 голосов
/ 16 марта 2011

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

...