1

我正在为 iOS 编写一个应用程序,我必须读取一个外部 xml 文件。我的程序逻辑运行良好。我用 NSLog 消息检查了几次。我的问题是,当我向我的 NSMutuableArray masterNewsList 添加一个新对象时,插入后每个对象都被最后插入的对象覆盖。我在这里有什么错误?我找不到它。

//  NewsData.h

#import <Foundation/Foundation.h>

@interface NewsData : NSObject

@property (nonatomic,copy) NSString *title;
@property (nonatomic,copy) NSString *date;
@property (nonatomic,copy) NSString *detail;
@property (nonatomic,copy) NSString *content;

-(id) initWithTitle:(NSString *)title  date:(NSString *)date detail:(NSString *)detail content:(NSString *)content;

@end


//NewsData.m

#import "NewsData.h"

@implementation NewsData

-(id)initWithTitle:(NSString *)title date:(NSString *)date detail:(NSString *)detail content:(NSString *)content{
 self = [super init];
 if (self) {
    _title = title;
    _date = date;
    _detail = detail;
    _content = content;
    return self;
}
return nil;
}

@end



//  NewsDataController.h


#import <Foundation/Foundation.h>

@class NewsData;

@interface NewsDataController : NSObject <NSXMLParserDelegate>

@property (nonatomic, copy) NSMutableArray *masterNewsList;

- (NSUInteger)countOfList;
- (NewsData *)objectInListAtIndex:(NSUInteger)theIndex;

@end



//  NewsDataController.m


#import "NewsDataController.h"
#import "NewsData.h"

@interface NewsDataController()

@property NSMutableString *title;
@property NSMutableString *description;
@property NSMutableString *content;
@property NSMutableString *date;

@property BOOL itemValue;
@property BOOL titleValue;
@property BOOL descriptionValue;
@property BOOL contentValue;
@property BOOL dateValue;

-(void) initializeDataList;
- (void)addNewsData:(NewsData *)newsData;

@end

@implementation NewsDataController

- (void) initializeDataList {
    NSMutableArray *newsList = [NSMutableArray array];
    self.masterNewsList = newsList;

    self.title = [NSMutableString stringWithString:@""];
    self.description = [NSMutableString stringWithString:@""];
    self.content = [NSMutableString stringWithString:@""];
    self.date = [NSMutableString stringWithString:@""];

    self.itemValue = false;
    self.contentValue = false;
    self.dateValue = false;
    self.titleValue = false;
    self.descriptionValue = false;

    NSData *xmlData = nil;
    xmlData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:@"http://www.somesite.de/?type=100"]];
    if (xmlData != nil) {
        NSXMLParser *theParser = [[NSXMLParser alloc] initWithData:xmlData];
        theParser.delegate = self;
        [theParser parse];
    }
     else{
        NewsData *newsData;
        newsData = [[NewsData alloc] initWithTitle:@"Es konnten keine News geladen werden" date: @"---" detail:@"Keine Verbindung zum Server" content:@"Bitte Netzwerkverbindung überprüfen!"];
        [self addNewsData:newsData];
    }
}

-(void) setMasterNewsList:(NSMutableArray *)newList{
    if (_masterNewsList != newList) {
        _masterNewsList = [newList mutableCopy];
    }
}

-(id) init{
    if (self = [super init]) {
        [self initializeDataList];
        return self;
    }
    return nil;
}

- (NSUInteger) countOfList{

    return [self.masterNewsList count];
}

- (NewsData *)objectInListAtIndex:(NSUInteger)theIndex{

    return [self.masterNewsList objectAtIndex:theIndex];
}

将对象添加到 masterNewsList 的方法

- (void) addNewsData:(NewsData *)newsData{

    [self.masterNewsList addObject:newsData];

}

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

    if ([elementName isEqualToString:@"item"]) {
        self.itemValue = true;
    }
    if ([elementName isEqualToString:@"title"]) {
        [self.title deleteCharactersInRange:NSMakeRange(0, self.title.length)];
        self.titleValue = true;
    }
    if ([elementName isEqualToString:@"description"]) {
        [self.description deleteCharactersInRange:NSMakeRange(0, self.description.length)];
        self.descriptionValue = true;
    }
    if ([elementName isEqualToString:@"content:encoded"]) {
        [self.content deleteCharactersInRange:NSMakeRange(0, self.content.length)];
        self.contentValue = true;
    }
    if ([elementName isEqualToString:@"pubDate"]) {
        [self.date deleteCharactersInRange:NSMakeRange(0, self.date.length)];
        self.dateValue = true;
    }
 }

在这里,我创建了一种 NewsData 的新对象,然后调用 addNewsData 方法

-(void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
    if ([elementName isEqualToString:@"item"]) {
        NewsData *newsData;
        newsData = [[NewsData alloc] initWithTitle:self.title date:self.date detail:self.description content:self.content];
        [self addNewsData:newsData];
        self.itemValue = false;
    }
    if ([elementName isEqualToString:@"title"]) {
        self.titleValue = false;
    }
    if ([elementName isEqualToString:@"description"]) {
        self.descriptionValue = false;
    }
    if ([elementName isEqualToString:@"content:encoded"]) {
        self.contentValue = false;
    }
    if ([elementName isEqualToString:@"pubDate"]) {
        self.dateValue = false;
    }
}

-(void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
    if (self.itemValue && self.titleValue) {
        [self.title appendString:string];
    }
    if (self.itemValue && self.descriptionValue) {
        [self.description appendString:string];
    }
    if (self.itemValue && self.contentValue) {
        [self.content appendString:string];
    }
    if (self.itemValue && self.dateValue) {
        [self.date appendString:string];
    }
}

-(void) parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock{
    if (self.itemValue && self.contentValue) {
        [self.content appendString:[[NSString alloc] initWithData:CDATABlock encoding:NSUTF8StringEncoding]];
    }
}



@end
4

2 回答 2

1

你的错误在这里:

if (self) {
    // None of these assignments copies the incoming mutable strings.
    // When strings change later on, so do titles, details, content, and so on.
    _title = title;
    _date = date;
    _detail = detail;
    _content = content;
    return self;
}

您正在使用对标记的属性的支持变量进行赋值copy。切换到分配给属性,您的问题将得到解决:

if (self) {
    // Since your property is correctly marked `copy` (a good idea for NSString)
    // these assignments will make copies of mutable strings,
    // preventing the unwanted modifications.
    self.title = title;
    self.date = date;
    self.detail = detail;
    self.content = content;
    return self;
}
于 2013-01-31T14:15:30.260 回答
0

我不完全确定是什么导致了这个问题,但我强烈建议你寻找 DDXML 并使用那一小组类来处理 xml。它们为节点、子节点和其他东西提供了简单的 getter,使用它比自己解析 XML 要容易得多。

干杯

于 2013-01-31T14:15:18.193 回答