27

わかりました、 を介して画像が非同期にダウンロードされているをそれぞれ含むUITableViewカスタムがあります。すべてのかなり標準的なもの...UITableViewCellUIImageViewNSURLConnection

問題は、テーブルがスクロールすると、新しい画像がバックグラウンドで正しくダウンロードされますが、テーブルの動きが止まるまでレンダリングされないことです。

テーブルが動いているときでもコンテンツをレンダリングするにはどうすればよいですか? ありがとう。

- アップデート -

よく見てみるとNSURLConnection、テーブルのスクロールが止まるまでデリゲート メソッドが起動していないことがわかりました。理由がわからない。どんな助けでも素晴らしいでしょう。

4

4 に答える 4

65

スクロールを停止するまで接続委任メッセージが発火しない理由は、スクロール中に実行ループがUITrackingRunLoopMode. デフォルトでは、スクロール中NSURLConnectionにのみスケジュールされるNSDefaultRunLoopModeため、スクロール中にメッセージは表示されません。

「一般的な」モードで接続をスケジュールする方法は次のUITrackingRunLoopModeとおりです。

NSURLRequest *request = ...
NSURLConnection *connection = [[NSURLConnection alloc]
                               initWithRequest:request
                               delegate:self
                               startImmediately:NO];
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop]
            forMode:NSRunLoopCommonModes];
[connection start];

初期化子で指定する必要があることに注意してくださいstartImmediately:NO。これは、開始後でも実行ループモードを変更できることを示唆する Apple のドキュメントに反しているようです。

于 2010-01-03T15:45:16.703 に答える
1

NSRunLoopを読んでください。スクロール中、実行ループはNSEventTrackingRunLoopModeで実行されており、NSURLConnectionはそのモードに含まれていないと思われます。NSURLConnectionのscheduleInRunLoop:forMode:を呼び出すことでこれを回避できる可能性があります。これにより、スクロール中にダウンロードが発生する可能性があります。

これはおそらくスクロールパフォーマンスに影響を及ぼします。これが、そもそも個別の実行ループモードの理由である可能性があります。しかし、それを試してみて、それがどのように感じるかを見てください!

于 2009-12-01T20:30:39.990 に答える
1

画像のダウンロードと更新をNSOperationでラップすると、テーブルビューがスクロールするときに更新が行われます。

NSOperationのもう1つの利点は、セルが画面外を滑るように操作をキャンセルできることです。特にユーザーが長いリストをすばやくスクロールする場合は、ユーザーの応答性が大幅に向上します。今年のAppleのテクニカルトークは、このテクニックを奨励しました。

リストがそれほど長くない場合、またはリストの読み込みを続行したい場合は、代わりにNSOperationの優先順位を操作できます。

于 2009-12-07T19:41:07.183 に答える
0

まず...あなたの接続はおそらく mainRunLoop に到達するまで開始されておらず、そこでスクロール アニメーションも処理されています。

私は同じ問題に遭遇し、画像の接続を作成時にすぐに開始するように指示することで修正しました。

    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:wrapper.request delegate:wrapper];

    [connection start];

画像を受け取り、cell.imageView.image を受け取った画像に設定する完了ルーチンでは、このセルが現在テーブルに表示されているセルの 1 つに属しているかどうかを確認する必要があります...そうであれば [ tableView reloadData]。

    NSInteger itemIndex = theIndexInTheRowDataOfTheCellYouStuffedTheImage

    NSArray *indicies = [_tableView indexPathsForVisibleRows];
    NSUInteger rows = indicies.count;

    if (rows > 0 &&
        itemIndex >= ((NSIndexPath *)[indicies objectAtIndex:0]).row &&
        itemIndex <= ((NSIndexPath *)[indicies objectAtIndex:rows - 1]).row)
    {       
        [_tableView reloadData];
    }
于 2009-12-02T23:47:50.383 に答える