2013-08-30 60 views
1

我想我在正确的轨道上,但只是想在这里仔细检查。我最近开始使用AFNetworking从数据库中获取一个大的XML文件,然后我需要解析(我弄清楚了这一部分)。我希望解析发生在后台线程上,然后在主线程上更新我的UI。所以我加了AFXMLRequestOperation成功块内的另一个dispatch_async块: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方法更新相同的对象/集合的代码(例如驱动用户界面),则必须小心同步这些共享资源。 (有关同步资源的详细信息,请参阅线程编程指南和/或并发编程指南的Eliminating Lock Based Code部的Synchronization部分。

    就个人而言,我喜欢的NSXMLParserDelegate代码移到单独的类,并为单个请求实例化,这样我就知道我的请求和后续解析过程永远不会成为同步问题的来源。您仍然需要同步更新模型/存储过程,但是您可以通过在主队列上执行最终更新来实现此目的。

  2. 您的用户界面是否允许您在第一个XML请求进行时发出另一个XML请求?如果没有,你很好。

    如果用户可以在第一个请求正在进行时发起第二个请求,它会向您打开(假定不太可能)情形,即可以使用同一个委托对象实例执行两个并发处理请求。显然,您可以通过阻止后续请求直到完成第一个请求(例如,禁用请求刷新的UI元素)或使用串行队列,或将解析器移动到您将为每个请求实例化的单独类中来解决此问题。就我个人而言,我倾向于使这个解析请求可以被取消,并且发出新的请求会取消任何之前正在进行的请求。

当我看着你的代码示例时,这些是两个并发相关的问题。事实上,这些都不是你的特定实现的问题。话虽如此,但代码与其他实现密切相关的事实本身就是一个问题。

+1

感谢您的输入Rob。事实上,你所描述的两个观察结果对我来说都不是问题。另外,我在一个单独的课程中进行解析(或多或少地遵循他们的iOS书中的Conway/Hillegass方法),但为了清晰起见,仅删除了该示例。 – Koen

+0

我实际上在一个关于魔法记录的问题中运行。正如这里所说的https://github.com/magicalpanda/MagicalRecord/issues/298,我不能在后台线程上使用MR_createEntity。而使用MR_createEntity创建实体正是我在解析XML时所做的。所以我需要重新思考这个策略。 – Koen

+0

@Koen啊,好的。我不知道你在做什么'NSXMLParserDelegate'方法。也许将XML解析为一些集合(无论嵌套数组和字典的适当组合是否适合您的数据),然后让您回发到主队列的代码采用该结构并执行“魔法记录”。祝你好运! – Rob