2

私は、デバッグしようとしている血まみれのひどいコードを継承しました。

NSXMLParser を使用して、RSS フィードを解析しています。parser:didEndElement:etc: では、新しいアイテムが表示されるたびに、UITableView の reloadData メソッドを呼び出す別のメソッドを起動します。ただし、reloadData メソッドは呼び出されたときに呼び出されるのではなく、後で ... parserDidEndDocument: ... の後、すべてが一度に起動します。

reloadData リクエストがどこかでキューに入れられ、解析スレッドでブロックされているようです。

必要なときではなく、指示したときに reloadData を強制的に起動するにはどうすればよいですか。私の問題は、すべてのニュース項目がロードされた後にのみリロードされるため (そしてそれらはたくさんあります)、UI エクスペリエンスが最適ではないことです。

4

1 に答える 1

2

あなたの推測は正しいです。ユーザー インターフェイスの更新は、プログラム制御がメインの実行ループに戻ったときにのみ行われます。NSXMLParserただし、完全に同期的に動作します。parseメソッドは XML データ全体を解析し (デリゲート関数などを呼び出します)、解析が完了したときにのみ戻ります。したがって、呼び出しreloadDataparser:didEndElement:...もすぐに目に見える効果はありません。

reloadDataXML データの解析に非常に時間がかかり、メソッドが返されたときに呼び出すことができない場合parseは、解析操作を別のスレッドに移動する必要があります。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [myParser parse];
});

dispatch_asyncすぐに戻り、解析はバックグラウンド スレッドで行われます。したがって、デリゲート メソッドはバックグラウンド スレッドでも呼び出されます。UI の更新はメイン スレッドでのみ行う必要があるため、次のように進めることができます parser:didEndElement:...

YourType newObject = ... // create new object from XML data
dispatch_async(dispatch_get_main_queue(), ^{
    // assuming that self.dataArray is your data source array for the table view 
    int newRow = [self.dataArray count]; // row number for new object
    [self.dataArray addObject:newObject]; // add to your data source
    // insert row in table view:
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:newRow inSection:0];
    [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                          withRowAnimation:UITableViewRowAnimationAutomatic];
});

insertRowsAtIndexPathsの代わりに使用reloadDataすると、アニメーションで「よりスムーズな」UI 更新が得られます。

私のサンプル コードに構文エラーが多すぎないこと、およびそれが役立つことを願っています。それ以外の場合は、お気軽にお問い合わせください。

于 2012-10-14T06:58:50.103 に答える