NSMutableArray多维覆盖本身

时间:2014-01-22 18:19:59

标签: ios objective-c xml arrays multidimensional-array

我正在尝试从XML文档中检索数据并将其存储在多维NSMutableArray中。问题是它似乎在覆盖自己?

我在ViewDidLoad方法中声明了数组cols和rows。像这样:

rows = [[NSMutableArray alloc] init];
cols = [[NSMutableArray alloc] init];

XML解析方法是:

- (void)parser:(NSXMLParser *)parser 
    didStartElement:(NSString *)elementName 
    namespaceURI:(NSString *)namespaceURI 
    qualifiedName:(NSString *)qualifiedName 
    attributes:(NSDictionary *)attributeDict
{  
    if ([elementName isEqualToString:@"song"]) {

        title = [attributeDict valueForKey:@"title"];
        songId = [attributeDict valueForKey:@"id"];
        singer = [attributeDict valueForKey:@"author"];
        theDuration = [attributeDict valueForKey:@"duration"];
        theLink = [attributeDict valueForKey:@"link"];

        [cols addObject: title];
        [cols addObject: songId];
        [cols addObject: singer];
        [cols addObject: theDuration];
        [cols addObject: theLink];

        [rows addObject: cols];   
    }
}

这是我的XML文档。正如你所看到的,前两首歌曲的id是0,下一首歌曲是1,接下来的两首歌曲是2.问题在于,数组似乎将所有6个don对象中的0作为id。

<?xml version="1.0"?>
<Lists>
<playlist title="Quo Vadis" id="0"/>
    <song title="One Perfect Day" link="m01MYOpbdIk" duration="3:15" author="Rune RK" id="0" />
    <song title="two Perfect Day" link="m01MYOpbdIk" duration="3:15" author="Rune RK" id="0" />

<playlist title="Lord of the Rings" id="1"/>
    <song title="three Perfect Day" link="m01MYOpbdIk" duration="3:15" author="Rune RK" id="1" />
    <song title="fourth Perfect Day" link="m01MYOpbdIk" duration="3:15" author="Rune RK" id="1" />
<playlist title="Face" id="2"/>
    <song title="five Perfect Day" link="m01MYOpbdIk" duration="3:15" author="Rune RK" id="2" />
    <song title="six Perfect Day" link="m01MYOpbdIk" duration="3:15" author="Rune RK" id="2" />
</Lists>

我用它来打印它:

NSLog(@"%@", [[rows objectAtIndex:3] objectAtIndex:1 ]);

2 个答案:

答案 0 :(得分:2)

您似乎正在为每一行重复使用相同的cols实例。你不能这样做。您需要为每一行创建一个新的cols实例:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
    if ([elementName isEqualToString:@"song"]) {
        title = attributeDict[@"title"];
        songId = attributeDict[@"id"];
        singer = attributeDict[@"author"];
        theDuration = attributeDict[@"duration"];
        theLink = attributeDict[@"link"];

        NSArray *cols = @[ title, songId, singer, theDuration, theLink ];

        [rows addObject: cols];
    }
}

删除cols ivar。此更新不需要它。

此外,除非您真的想要使用KVC,否则不要将valueForKey:与词典一起使用。使用objectForKey:或我在这里使用新的现代语法。

答案 1 :(得分:0)

这是rmaddy(伟大)答案的副产品。使用文字数组时 - 例如@[thing1, thing2] - 如果有任何事情nil,你就会遇到麻烦。防止这种情况的一种方法是在创建阵列之前检查这一点。 C trinary运算符是一种很好的方法:

thing1 = dict[@"key"] ? dict[@"key"] : @"";

如果thing1为非dict[@"key"],则将nil设置为nil,如果为thing1 = dict[@"key"] ?: @""; ,则将其设置为空字符串。简而言之(也更有效率):

- (void)parser:(NSXMLParser *)parser 
    didStartElement:(NSString *)elementName 
    namespaceURI:(NSString *)namespaceURI 
    qualifiedName:(NSString *)qualifiedName 
    attributes:(NSDictionary *)attrs
{  
   // presumably other code ...
   if ([elementName isEqualToString:@"song"]) {
        title = attrs[@"title"] :? @"";
        songId = attrs[@"id"] :? @"";
        singer = attrs[@"author"] :? @"";
        theDuration = attrs[@"duration"] :? @"";
        theLink = attrs[@"link"] :? @"";

        [rows addObject:@[ title, songId, singer, theDuration, theLink ]];
    }
}

在代码中使用它,并假设这些变量都是字符串:

cols

因为我觉得它更干净,所以我也跳过添加局部变量{{1}},并直接添加文字数组。