0

iPhone で NSXMLParser を使用して XML を解析する場合、奇妙な問題があります。アプリを起動するときに、バックグラウンドで RSS フィードによって入力される 4 つのテーブル ビューをプリロードしたいと考えています。

テーブルビューを 1 つずつ初期化すると、すべての読み込み、解析、および表示が魅力的に機能します。しかし、すべてのビューを一度に (同時に) 初期化しようとすると、XML パーサー インスタンスが互いに干渉しているように見えます。1 つの XML-Feed からのデータが、属していない他の xml-parser インスタンスに「ブロードキャスト」されます。例:「これは私の名前です」という「チームメンバー」の項目があります。このバグが発生すると、別の xml フィードからの文字列が追加されます。つまり、"This is my name58" という結果になります。ここで、58 は他のビューからの何かのチャート位置です。「58」は、他のインスタンスでは見逃されているようです。

このバグは、NSXMLParser-delegate メソッドが原因で発生しているように見えます。

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    if (!currentStringValue) {
        currentStringValue = [[NSMutableString alloc] initWithCapacity:50];
    }
    [currentStringValue appendString:string];   
}

この場合、「偶然にも」バイトが、属していない文字列に追加されます。

奇妙なことに、NSXMLParser のすべてのインスタンスは一意であり、独自の ViewController にアタッチされた独自のデリゲートを持っています。すべての解析要求は、独自の (これも一意の名前の) Autorelease-pool を使用して、独自のバックグラウンド タスクを生成します。

ViewController で次のように NSXMLParser を呼び出しています。

// prepare XML saving and parsing
currentStringValue = [[[NSMutableString alloc] initWithCapacity:50] retain];    
charts = [[NSMutableArray alloc] init];

NSURL *url = [[NSURL alloc] initWithString:@"http://(SOME XML URL)"];
xmlParser = [[[NSXMLParser alloc] initWithContentsOfURL:url] retain];

//Set delegate
[xmlParser setDelegate:self];

//loading indicator 
progressWheel = [[[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(150.0,170.0,20.0,20.0)] autorelease];
progressWheel.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;

[self.view addSubview:progressWheel];
[progressWheel startAnimating];

// start loading and parsing the xml-feed in the background
//[self performSelectorInBackground:@selector(parse:) withObject:xmlParser]; -> I also tried this
[NSThread detachNewThreadSelector:@selector(parse:) toTarget:self withObject:xmlParser];

これは、フィードを解析するバックグラウンド タスクの 1 つです。

-(void)parse:(NSXMLParser*)myParser {

NSAutoreleasePool *schedulePool = [[NSAutoreleasePool alloc] init];

BOOL success = [myParser parse];

if(success) {
    NSLog(@"No Errors. xmlParser got: %@", myParser);

    (POST-PROCESSING DETAILS OF THE DATA RETURNED)

    [self.tableView reloadData];            

} else {    
    NSLog(@"Couldn't initalize XMLparser");
}

[progressWheel stopAnimating];

[schedulePool drain];

[myParser release]; 

}

この問題の原因は何ですか? バックグラウンド タスクを正しい方法で呼び出していますか? すべての XML-Parser が独自の一意のインスタンスを持っているのに、なぜこのバグが近づいているのでしょうか?

4

2 に答える 2

6

progressWheelバックグラウンド スレッド内からUI 要素 ( など) を更新しないでください。UI の更新はメイン スレッドで行う必要があります。

-performSelectorOnMainThread:withObject:waitUntilDone:バックグラウンド スレッド内から UI 要素を更新するために使用します。

于 2010-04-29T19:14:58.253 に答える
0

iPhone 用のオープン ソースRSS/Atom パーサーをリリースしました。これにより、Web フィードの読み取りと解析が非常に簡単になります。

データを非同期的にダウンロードするように設定することも、バックグラウンド スレッドで同期的に実行してフィード データを収集することもできます。

お役に立てれば!

于 2010-07-21T11:24:48.190 に答える