2013-09-28 62 views
0

我創建了一個名爲tempArrayNSMutableArray,它包含我想要的三個元素的字符。目前,當我設置斷點並讓解析器運行時,每次都會正確更改,併爲我提供我需要的信息(緯度,經度,名稱)。addObject覆蓋的所有對象:使用NSXMLParser時

然後,當分析器呼籲「一個定位」的didEndElement...方法,我想補充tempArray名爲parsedNearMe主要NSMutableArray,應保存所有的A位置(每個有名稱,經緯度) 。

這一切都按預期工作。

問題: 每次我加tempArrayparsedNearMe,它增加了新的對象,而是將所有現有的對象到新對象的值。

我覺得是問題 我覺得現在的問題是,因爲我需要的元素設置爲tempArray,每一次我在覆蓋每parsedNearMe對象,因爲每個對象是指向同tempArray

可能的解決方案我已經嘗試或沒有運氣研究 -Somehow清除指針,以便我可以重複使用tempArray(或重新初始化嗎?) -dynamically代替每次tempArray創建一個新的名稱(不要」 t認爲是可能的Objective-C)

我欣賞任何建議,因爲我已經花了這麼多小時在這已經做了圈子。此外,我會喜歡當前的架構工作(獲取一個大數組數組,因此我可以調用1個數組並獲取所需的所有數據)。

我的代碼如下:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict 
{ 

    if ([elementName isEqualToString:@"a-location"]) 
    { 
     if (!tempArray) 
      tempArray = [[NSMutableArray alloc] init]; 
     return; 
    } 


    if ([elementName isEqualToString:@"latitude"]) 
    { 
     latitude = [[NSMutableString alloc] init]; 
     return; 
    } 


    if ([elementName isEqualToString:@"longitude"]) { 
     longitude = [[NSMutableString alloc] init]; 
     return; 
    } 


    if ([elementName isEqualToString:@"the-name"]) { 
     myName = [[NSMutableString alloc] init]; 
     return; 
    } 

} 



-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 
{ 
    currentString = [[NSMutableString alloc]init]; 
    [currentString appendString:string]; 

} 



- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 
{ 

    if ([elementName isEqualToString:@"latitude"]) { 
     [tempArray addObject:currentString]; 
     return; 
    } 

    if ([elementName isEqualToString:@"longitude"]) { 
     [tempArray addObject:currentString]; 
     return; 
    } 

    if ([elementName isEqualToString:@"the-name"]) { 
     [tempArray addObject:currentString]; 
     return; 
    } 

    if ([elementName isEqualToString:@"a-location"]) 
    { 
     [parsedNearMe setObject:tempArray forKey:[NSDate date]]; 
     [tempArray removeAllObjects]; 
    } 
} 

回答

1

有幾個問題:

  1. didEndElementa-location設定的日期鍵的值,但隨後發生的指針點到同一個對象並刪除該對象中的所有項目。因此,而不是:

    if ([elementName isEqualToString:@"a-location"]) 
    { 
        [parsedNearMe setObject:tempArray forKey:[NSDate date]]; 
        [tempArray removeAllObjects]; 
    } 
    

    你可能會替換成:

    if ([elementName isEqualToString:@"a-location"]) 
    { 
        [parsedNearMe setObject:tempArray forKey:[NSDate date]]; 
        tempArray = nil; // make sure you don't touch that object you just added to parsedNearMe 
    } 
    
  2. 我懷疑這個特殊的XML會存在這個問題,但是你foundCharacters認爲,一個單一的通話將返回所有的數據。這不是一個有效的假設。有時需要多次調用。

  3. 您還有foundCharacters爲您不感興趣的XML部分追加字符串。除了解析緯度,經度和名稱時,您應確保currentStringnil

所以,在最起碼,我建議類似以下內容:每個字典由一些隨機時間戳鍵控

- (void)parserDidStartDocument:(NSXMLParser *)parser 
{ 
    parsedNearMe = [[NSMutableDictionary alloc] init]; 
    currentString = nil; 
} 

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict 
{ 
    if ([elementName isEqualToString:@"a-location"]) 
    { 
     tempArray = [[NSMutableArray alloc] init]; 
    } 
    else if ([elementName isEqualToString:@"latitude"] || 
      [elementName isEqualToString:@"longitude"] || 
      [elementName isEqualToString:@"the-name"]) 
    { 
     currentString = [[NSMutableString alloc] init]; 
    } 
} 

-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 
{ 
    [currentString appendString:string]; 
} 

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 
{ 
    if ([elementName isEqualToString:@"latitude"] || 
     [elementName isEqualToString:@"longitude"] || 
     [elementName isEqualToString:@"the-name"]) 
    { 
     [tempArray addObject:currentString]; 
     currentString = nil; 
    } 
    else if ([elementName isEqualToString:@"a-location"]) 
    { 
     [parsedNearMe setObject:tempArray forKey:[NSDate date]]; 
     tempArray = nil; 
    } 
} 

這反映了當前的邏輯,創造詞典,和值item是緯度,經度和名稱的數組。

我個人認爲,這樣的設計從兩個額外的缺陷所害,但:

  1. 你一些隨機對象,[NSDate date]鍵控你的字典。這沒有價值。你也可以使這個數組。您的經緯度和名稱數組不明確。您的數據結構高度依賴於XML文件中項目的順序。如果你打算使用任何字典,我會在這裏使用它。

因此,底線,而不是字典的值是數組,我會翻轉。我會建議一個字典對象的數組。我認爲parsedNearMe應該是NSMutableArray。而代替NSMutableArraytempArray,你應該使用一個NSMutableDictionary稱爲tempDictionary

首先,定義了幾個實例變量:

NSMutableArray *parsedNearMe;   // this was a NSMutableDictionary 
NSMutableDictionary *tempDictionary; 

然後你NSXMLParserDelegate程序可能看起來像:

- (void)parserDidStartDocument:(NSXMLParser *)parser 
{ 
    parsedNearMe = [[NSMutableArray alloc] init]; 
    currentString = nil; 
} 

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict 
{ 
    if ([elementName isEqualToString:@"a-location"]) 
    { 
     tempDictionary = [[NSMutableDictionary alloc] init]; 
    } 
    else if ([elementName isEqualToString:@"latitude"] || 
      [elementName isEqualToString:@"longitude"] || 
      [elementName isEqualToString:@"the-name"]) 
    { 
     currentString = [[NSMutableString alloc] init]; 
    } 
} 

-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 
{ 
    [currentString appendString:string]; 
} 

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 
{ 
    if ([elementName isEqualToString:@"latitude"] || 
     [elementName isEqualToString:@"longitude"] || 
     [elementName isEqualToString:@"the-name"]) 
    { 
     [tempDictionary setObject:currentString forKey:elementName]; 
     currentString = nil; 
    } 
    else if ([elementName isEqualToString:@"a-location"]) 
    { 
     [parsedNearMe addObject:tempDictionary]; 
     tempDictionary = nil; 
    } 
} 

或者,如果您想將NSNumber對象的經度和緯度存儲爲字符串,則可以將didEndElement替換爲:

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 
{ 
    if ([elementName isEqualToString:@"latitude"] || 
     [elementName isEqualToString:@"longitude"]) 
    { 
     [tempDictionary setObject:@([currentString doubleValue]) forKey:elementName]; 
     currentString = nil; 
    } 
    else if ([elementName isEqualToString:@"the-name"]) 
    { 
     [tempDictionary setObject:currentString forKey:elementName]; 
     currentString = nil; 
    } 
    else if ([elementName isEqualToString:@"a-location"]) 
    { 
     [parsedNearMe addObject:tempDictionary]; 
     tempDictionary = nil; 
    } 
} 
+0

結構非常好的答案,謝謝。 雖然我還沒有嘗試過你的解決方案,但我相信這將解決我的問題:tempArray = nil; 我也同意你的設計建議。實際上,我原本只有兩個NSMutableArrays,但最終以當前的字典設計結束了,因爲我只是想了很多方法,並且認爲使用NSDictionary和鍵可以解決每次覆蓋對象的問題。 – Joel

+0

此外,這也是爲什麼我試圖把他們的關鍵隨機日期。出於某種原因,我認爲給它一個唯一的名字(日期)會阻止對象被覆蓋。我也嘗試在0開始一個計數器,並使用數字作爲關鍵。感謝您清除這:)。 – Joel