addObject覆盖的所有对象:使用NSXMLParser时
我创建了一个名为tempArray
的NSMutableArray
,它包含我想要的三个元素的字符。目前,当我设置断点并让解析器运行时,每次都会正确更改,并为我提供我需要的信息(纬度,经度,名称)。addObject覆盖的所有对象:使用NSXMLParser时
然后,当分析器呼吁“一个定位”的didEndElement...
方法,我想补充tempArray
名为parsedNearMe
主要NSMutableArray
,应保存所有的A位置(每个有名称,经纬度) 。
这一切都按预期工作。
问题: 每次我加tempArray
到parsedNearMe
,它增加了新的对象,而是将所有现有的对象到新对象的值。
我觉得是问题 我觉得现在的问题是,因为我需要的元素设置为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];
}
}
有几个问题:
-
的
didEndElement
为a-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 }
我怀疑这个特殊的XML会存在这个问题,但是你
foundCharacters
认为,一个单一的通话将返回所有的数据。这不是一个有效的假设。有时需要多次调用。您还有
foundCharacters
为您不感兴趣的XML部分追加字符串。除了解析纬度,经度和名称时,您应确保currentString
为nil
。
所以,在最起码,我建议类似以下内容:每个字典由一些随机时间戳键控
- (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是纬度,经度和名称的数组。
我个人认为,这样的设计从两个额外的缺陷所害,但:
你一些随机对象,
[NSDate date]
键控你的字典。这没有价值。你也可以使这个数组。您的经纬度和名称数组不明确。您的数据结构高度依赖于XML文件中项目的顺序。如果你打算使用任何字典,我会在这里使用它。
因此,底线,而不是字典的值是数组,我会翻转。我会建议一个字典对象的数组。我认为parsedNearMe
应该是NSMutableArray
。而代替NSMutableArray
叫tempArray
,你应该使用一个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;
}
}
结构非常好的答案,谢谢。 虽然我还没有尝试过你的解决方案,但我相信这将解决我的问题:tempArray = nil; 我也同意你的设计建议。实际上,我原本只有两个NSMutableArrays,但最终以当前的字典设计结束了,因为我只是想了很多方法,并且认为使用NSDictionary和键可以解决每次覆盖对象的问题。 – Joel
此外,这也是为什么我试图把他们的关键随机日期。出于某种原因,我认为给它一个唯一的名字(日期)会阻止对象被覆盖。我也尝试在0开始一个计数器,并使用数字作为关键。感谢您清除这:)。 – Joel