RSS フィードからデータ (タイトル、画像など) を解析し、テーブルビューに表示する単純な iPhone アプリがあります。
viewDidLoad には、フィードの最初のページに到達し、fetchEntriesNew メソッドを呼び出して tableview にロードするための初期カウンター値があります。
- (void)viewDidLoad
{
[super viewDidLoad];
counter = 1;
[self fetchEntriesNew:counter];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(dataSaved:)
name:@"DataSaved" object:nil];
}
- (void) fetchEntriesNew:(NSInteger )pageNumber
{
channel = [[TheFeedStore sharedStore] fetchWebService:pageNumber withCompletion:^(RSSChannel *obj, NSError *err){
if (!err) {
int currentItemCount = [[channel items] count];
channel = obj;
int newItemCount = [[channel items] count];
NSLog(@"Total Number Of Entries Are: %d", newItemCount);
counter = (newItemCount / 10) + 1;
NSLog(@"New Counter Should Be %d", counter);
int itemDelta = newItemCount - currentItemCount;
if (itemDelta > 0) {
NSMutableArray *rows = [NSMutableArray array];
for (int i = 0; i < itemDelta; i++) {
NSIndexPath *ip = [NSIndexPath indexPathForRow:i inSection:0];
[rows addObject:ip];
}
[[self tableView] insertRowsAtIndexPaths:rows withRowAnimation:UITableViewRowAnimationBottom];
[aiView stopAnimating];
}
}
}];
[[self tableView] reloadData];
}
ユーザーがテーブルビューの下部に到達すると、次を使用してフィードの次のページに到達し、最初に読み込まれた最初のページの下部に読み込みます:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
float endScrolling = scrollView.contentOffset.y + scrollView.frame.size.height;
if (endScrolling >= scrollView.contentSize.height)
{
NSLog(@"Scroll End Called");
NSLog(@"New Counter NOW is %d", counter);
[self fetchEntriesNew:counter];
}
}
更新 2: これは、私が解決できない問題のわかりやすい説明です: たとえば、RSS フィードの各ページに 10 のエントリがあります。アプリが起動し、タイトルやその他のラベルがすぐに読み込まれ、画像が遅延して読み込まれ、最後に終了します。ここまでは順調ですね。ユーザーはスクロールして一番下に到達し、一番下に到達するとスクロール デリゲート メソッドが使用され、カウンターが 1 から 2 に増加し、fetchEntriesNew メソッドに RSS フィードの 2 ページ目に到達するように指示します。プログラムは、以前にフェッチした最初の 10 個のエントリの最後にある次の 10 個のエントリのロードを開始します。これが続くと、ユーザーがスクロールして一番下に到達するたびに、プログラムはさらに 10 個のエントリを取得し、新しい行は以前に取得した行の下に配置されます。ここまでは順調ですね。
ここで、ユーザーが現在、画像が完全に読み込まれた 3 ページ目にいるとします。ページ 3 が完全に読み込まれるため、現在、テーブルビューには 30 のエントリがあることを意味します。ユーザーが一番下までスクロールすると、カウンターがインクリメントされ、最初の 30 エントリの一番下にある RSS フィードのページ 4 から、テーブルビューが新しい行の入力を開始します。タイトルはすぐに読み込まれるため、行が作成され、画像がダウンロードされている間 (まだ完全にはダウンロードされていません)、ユーザーはすぐに一番下に移動します。現在ダウンロードの途中で、4番目のもののロードを再開します。
すべきことは、前のページの画像がダウンロード中かどうかに関係なく、ユーザーがテーブルビューの一番下に到達したときに、次のページからタイトルなどを保持することです。
プロジェクトのデータのダウンロードと永続化に問題はなく、すべてのデータはアプリケーションの実行間で永続化されます。
誰かが私を正しい方向に向けるのを手伝ってくれますか? 前もって感謝します。
更新 3: @Sergio の回答に基づいて、これは私がしたことです:
1) archiveRootObject [NSKeyedArchiver archiveRootObject:channelCopy toFile:cachePath] への別の呼び出しを追加しました。after [channelCopy addItemsFromChannel:obj];
この時点で、同じバッチを何度も破棄して再ロードすることはありません。まさに私が望んでいたことです。ただし、前のページの画像が完全に読み込まれずに次のページに到達するために複数回スクロールすると、画像が保持されません。
2) 彼が答えで説明したように、Bool の使い方がわかりません。これは私がしたことです: @property Bool myBool を追加しました。TheFeedStore で合成し、新しく追加された archiveRootObject:channelCopy の後に NO に設定し、fetchEntries メソッドの最初の段階で ListViewController で YES に設定します。うまくいきませんでした。
3)私はまた、私が問題全体に対処している方法は、パフォーマンスの悪徳であることに気付きました. キャッシュ外の画像を使用して、一種のキャッシュとして処理する方法はわかりませんが。画像に別のアーカイブ ファイルを使用することをお勧めしますか?
私の問題を解決するために貢献してくれたすべての人に感謝します。