5

RSS フィードを解析するために NSXmlParser を使用しています。これまでのところ、すべてうまくいっています。

RSS フィードには、最終的に数十または数百の投稿が含まれることになると予想しています。私の現在の解決策は、RSS フィード全体を読み取り、結果を表示することです。ただし、最初の 10 件の投稿のみを読みたいと考えています (数百のアイテムを解析するのを防ぐため)。その後 (ユーザーがテーブルの最後に到達したときなど)、次の 10 件の投稿を解析します。

したがって、私の質問は、最初の 10 件の投稿を解析し、次の 10 件の投稿を解析し、次の 10 件の投稿などを解析する方法です...

すべての投稿を取得するために使用しているものは次のとおりです。

- (void)parseXMLFileAtURL:(NSString *)URL
{   
    myArray = [[NSMutableArray alloc] init];

    //convert the path to a proper NSURL or it won't work
    NSURL *xmlURL = [NSURL URLWithString:URL];

    rssParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
    [rssParser setDelegate:self];
    [rssParser parse];

}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
    //error
}

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

    currentElement = [elementName copy];

    if ([elementName isEqualToString:@"item"]) {
        //clear out our story item caches...
        item = [[NSMutableDictionary alloc] init];

    }

}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{     

    if ([elementName isEqualToString:@"item"]) {
        // save values to an item, then store that item into the array...
    }

}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{

    // save the characters for the current item...

}

- (void)parserDidEndDocument:(NSXMLParser *)parser {

    [myTable reloadData];

}
4

4 に答える 4

7

他の回答とは異なるスタイルの回答で、パーサーが 10 と 100 の差が人間が測定できる重要な量である場合に解析にこれほど長い時間がかかっている場合、何か間違ったことをしているということに貢献したいと思います。おそらく最善の方法は次のとおりです。

  1. 解析コードをプロファイリングして速度低下を見つけます (または、よりパフォーマンスの高い XML ライブラリを見つけます)。
  2. バックグラウンド スレッドでロット全体を解析する
  3. 最初の 10 件のみをユーザーに表示し、
  4. メモリから残りを表示します。

一度にすべてを解析するとコードが単純になり、バグが少なくなり、RSS「ページ」を 1 つずつ「ロード」(表示) するのが非常に高速になり、ユーザーはあなたを気に入るはずです (例については Instagram を参照してください)。偽装速度について)

于 2012-07-08T02:09:40.363 に答える
0

@coneybeareに同意します。バックグラウンドスレッドでxmlを解析し、結果をメモリに保存するのが正しい方法のようです。

それにもかかわらず、「ページごとに」xml を解析したい場合は、xmlParseChunkfrom libxmlを使用して実行できます (たとえば、 XMLPerformance サンプルを参照してください)。アイテムを手動で計算し、余剰をどこかに保存する必要がありますが、箱から出してすぐに使える最も近い機能だと思います。

もう 1 つの方法は、Objective-C の無料のオープン ソース xml パーサー ( TBXMLの例のように DOM パーサーの場合もあります) を使用し、その内部の解析ループを自分に合った方法で分割することです。

于 2012-07-08T12:26:14.070 に答える
0

クラスヘッダーにカウント変数を必ず作成してください。

...
@private
  NSUInteger rssCounter;
...
@property (nonatomic, assign) NSUInteger rssCounter;
...

デリゲートの init メソッドで:

rssCounter = 0;

次に、要素の終わりに到達するたびにこの変数を単純にインクリメントし、@Metalmi で述べ​​られているように、要素を開始するときに if else ブロックで中止解析を使用します。

その後、さらに 10 個をロードする必要があるときに変数を 0 にリセットするメソッドを作成します。このメソッドは、プロセス全体を再度トリガーする必要があるときに呼び出すことができます。

何かのようなもの:

- (void)restartParsing:(NSString *)url
{
  rssCounter = 0
  [self parseXMLFileAtURL:url];
}

お役に立てれば。

于 2012-07-07T21:59:45.007 に答える
0

呼び出し[rssParser abortParsing]て解析を停止できます。停止したら、xml の最初の部分を手動で切り取る必要があります。または、Webサービスに何らかの方法で伝えます。NSXMLParser は、そこにジャンプするためのアクセスを提供しません。

于 2012-07-06T14:37:06.703 に答える