所以我在这里遇到了这个奇怪的问题。我们在NSXMLParser
上构建了一个解析器,它首先实例化一个对象,然后根据刚刚结束的XML元素设置它的值。基本上,它将XML文件转换为可重用的NSObject
。
现在我在解析器中设置一个断点,以确定是否正确设置了值。
嗯,看起来不错。正确解析。让我为此编写一个单元测试。
assertThat([parsedPerson dateOfBirth], is(equalTo(@"22.06.1949")));
现在发生这种情况。我得到以下控制台输出:
Expected "22.06.1949", but was "22.06.1949 "
什么?这些空白来自哪里?让我在单元测试中调试对象。</ p>
相同的内存地址?相同的对象?这些空白来自哪里?有人有想法吗?
答案 0 :(得分:2)
我发现它与解析器本身有关,而且空格实际上是XML文件中的真实空格。
我们有(以下)设置:
- (void)parser: (NSXMLParser *) parser didStartElement: (NSString *) elementName namespaceURI: (NSString *) namespaceURI qualifiedName: (NSString *) qName attributes: (NSDictionary *) attributeDict {
[self setCurrentString: [NSMutableString string]];
}
- (void)parser: (NSXMLParser *) parser foundCharacters: (NSString *) string {
string = [string stringByReplacingOccurrencesOfString: @"\n" withString: @""];
string = [string stringByReplacingOccurrencesOfString: @"\t" withString: @""];
[currentString appendString: string];
}
- (void)parser: (NSXMLParser *) parser didEndElement: (NSString *) elementName namespaceURI: (NSString *) namespaceURI qualifiedName: (NSString *) qName {
if ([elementName isEqualToString: @"dateOfBirth"]) {
[theObject setDateOfBirth: currentString];
}
// ...
}
现在的问题是,将NSMutableString currentString
分配给此对象在这个地方是危险的,因为它会被foundCharacters
方法修改,因为它会在元素结束后继续查找字符。
这里的误解是,在将可变字符串分配给对象后,它不会被修改。
解决方案:当你真的希望它不被修改时,从字符串中创建一个不可变的字符串,即使你认为它不会。
- (void)parser: (NSXMLParser *) parser didEndElement: (NSString *) elementName namespaceURI: (NSString *) namespaceURI qualifiedName: (NSString *) qName {
NSString *parsedString = [NSString stringWithString:currentString]; // non-mutable copy made here
if ([elementName isEqualToString: @"dateOfBirth"]) {
[theObject setDateOfBirth: parsedString];
}
// ...
}