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

オブジェクトを masterNewList に追加するメソッド

- (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 を操作することを強くお勧めします。それらはノードや子などに単純なゲッターを提供し、XML を自分で解析するよりもはるかに簡単に操作できます。

乾杯

于 2013-01-31T14:15:18.193 に答える