2013-08-30 1 views
1

Я думаю, что я на правильном пути, но просто хотел дважды проверить здесь. Недавно я начал использовать AFNetworking для получения большого XML-файла из базы данных, который затем мне нужно разобрать (я понял, что эта часть была выяснена). Я бы хотел, чтобы разбор произошел в фоновом потоке, а затем обновил свой интерфейс в основном потоке. Поэтому я добавил еще один dispatch_async блок внутри блока успеха в AFXMLRequestOperation:AFNetworking: разбор xml в фоновом режиме

self.xmlOperation = 
[AFXMLRequestOperation XMLParserRequestOperationWithRequest: request 
                success: ^(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLParser *XMLParser) { 

                 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
                  XMLParser.delegate = self; 
                  [XMLParser setShouldProcessNamespaces:YES]; 
                  [XMLParser parse]; 

                  dispatch_async(dispatch_get_main_queue(), ^{ 
                   [self.searchResultViewController didFinishImport]; 
                   [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait]; 

                  }); 
                 }); 
                } 
                failure: ^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, NSXMLParser *XMLParser) { 
                 // show error 
                }]; 

[self.xmlOperation start]; 

ли правильный/правильно/предпочтительный способ сделать это?

+2

Да, это правильно. – rmaddy

ответ

1

Это выглядит довольно хорошо. Два наблюдения, хотя:

  1. ли какой-либо из вашего кода на основном потоке может получить доступ к любому из объектов активно обновляется ваши NSXMLParserDelegate методов? Если нет, все в порядке.

    Но если у вас есть какой-либо код (например, управляющий пользовательским интерфейсом), который обращается к тем же объектам/коллекциям, которые обновляют методы NSXMLParserDelegate, тогда вы должны быть осторожны в синхронизации этих общих ресурсов. (Для получения более подробной информации о синхронизации ресурсов см Synchronization раздел Руководства Threading программирования и/или часть параллелизма Руководство по программированию Eliminating Lock Based Code.)

    Лично я хотел бы переместить NSXMLParserDelegate код в отдельный класс и создать экземпляр для индивидуального запроса, таким образом, я знаю, что мой запрос и последующий процесс синтаксического анализа никогда не могут быть источником проблем синхронизации. Вам по-прежнему необходимо синхронизировать процесс обновления/хранения, но вы эффективно это делаете, выполняя это окончательное обновление в главной очереди.

  2. Поддерживает ли ваш пользовательский интерфейс другой запрос XML во время выполнения первого? Если нет, все в порядке.

    Если пользователь может инициировать второй запрос во время выполнения первого, он открывает вам сценарий (по общему признанию, маловероятный), что вы могли бы выполнять два одновременных запроса обработки, используя один и тот же экземпляр объекта-делегата. Понятно, что вы могли бы решить это, предотвратив последующие запросы до тех пор, пока первый не завершится (например, отключите элементы пользовательского интерфейса, запрашивающие обновление), или используйте последовательную очередь, или переместите анализатор в отдельный класс, который вы создадите для каждого запроса. Лично я был бы склонен сделать этот запрос анализа отменяемым и сделать выпуск нового запроса отменить любые предыдущие, текущие.

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

+1

Спасибо за ваш вклад. На самом деле ни одно из двух замечаний, которые вы описываете, не является проблемой в моем случае. Кроме того, я разбираюсь в отдельном классе (более или менее следуя подходу Conway/Hillegass в своей книге iOS), но просто удалил это для ясности этого примера. – Koen

+0

Я действительно работаю с проблемой Magical Record. Как указано здесь https://github.com/magicalpanda/MagicalRecord/issues/298, я не могу использовать MR_createEntity в фоновом потоке. И создание объектов с использованием MR_createEntity - это именно то, что я делал, анализируя XML. Поэтому мне нужно переосмыслить эту стратегию. – Koen

+0

@Koen Ах, хорошо. Я не знал, что вы делали в методах 'NSXMLParserDelegate'.Возможно, проанализируйте XML в какой-либо коллекции (независимо от того, какая соответствующая комбинация вложенных массивов и словарей для ваших данных), а затем код, который вы отправляете обратно в основную очередь, берете эту структуру и делаете материал Magical Record. Удачи! – Rob

Смежные вопросы