0

所以我在这里遇到了这个奇怪的问题。我们构建了一个解析器NSXMLParser,首先实例化一个对象,然后根据刚刚结束的 XML 元素设置它的值。基本上,它将 XML 文件转换为可重用的NSObject.

现在我在解析器中设置一个断点来确定这些值是否设置正确。

截图调试器

嗯,看起来不错。正确解析。让我为此编写一个单元测试。

assertThat([parsedPerson dateOfBirth], is(equalTo(@"22.06.1949")));

现在发生了这种情况。我得到以下控制台输出:

Expected "22.06.1949", but was "22.06.1949        "

什么?空格从何而来?让我在单元测试中调试对象。

截图调试器 2

相同的内存地址?同一个对象?空格从何而来?有人有想法吗?

4

1 回答 1

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];
    }

        // ...
}
于 2013-01-31T22:33:48.657 回答