I'm writing an app for iOS and i have to read an external xml file. My program logic is working very well. I checked that several times with NSLog messages. My problem is, when I'm adding an new object to my NSMutuableArray masterNewsList then is after the insertion every object overwritten by the last inserted object. What's my mistake here? I can't find it.
我正在为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];
}
Method who add the object to masterNewsList
将对象添加到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;
}
}
Here I'm creating the new object of kind NewsData and calling then the addNewsData Method
在这里,我正在创建一个类新闻的新对象,然后调用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
2 个解决方案
#1
1
Your mistake is here:
你的错误在这里:
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;
}
You are using assignments to backing variables of properties marked copy
. Switch to assigning to properties, and your problem will be fixed:
您正在使用赋值来支持标记为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;
}
#2
0
I'm not entirely sure what could be causing this problem, but I STRONGLY suggest you look for DDXML and use that small set of classes to work with xml. They provide simple getters for nodes and childs and stuff, and it's a hell of a lot easier to work with that than parsing the XML yourself.
我不完全确定是什么原因导致了这个问题,但我强烈建议您查找DDXML并使用一小组类来处理xml。它们为节点和子节点提供了简单的getter,与使用XML解析XML相比,使用它更加容易。
Cheers
干杯
#1
1
Your mistake is here:
你的错误在这里:
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;
}
You are using assignments to backing variables of properties marked copy
. Switch to assigning to properties, and your problem will be fixed:
您正在使用赋值来支持标记为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;
}
#2
0
I'm not entirely sure what could be causing this problem, but I STRONGLY suggest you look for DDXML and use that small set of classes to work with xml. They provide simple getters for nodes and childs and stuff, and it's a hell of a lot easier to work with that than parsing the XML yourself.
我不完全确定是什么原因导致了这个问题,但我强烈建议您查找DDXML并使用一小组类来处理xml。它们为节点和子节点提供了简单的getter,与使用XML解析XML相比,使用它更加容易。
Cheers
干杯