2013-08-30 51 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