0

私のアプリでは、URL から画像を読み込みます。

-(void)loadImages
{
    ...

    image1 = [UIImage imageWithData:[NSData dataWithContentsOfURL:imgUrl1]];
}

ダウンロードが完了するまでメイン スレッドがブロックされないようにするために、 次を使用して-viewDidAppearGCDでこのメソッドを呼び出します。

dispatch_async( dispatch_get_global_queue(0,0), ^{
            [self loadImages];
        });

ただし、最初に で開くview controllerと(長時間待っても) は空ですが、もう一度開くと画像が表示され、すべて問題ありません。imageViewimageViewview controller

私の間違いはどこですか?申し訳ありませんが、マルチスレッドは初めてです:)

編集tableView:私はまた、私がそれを取得したときに画像を使用することを忘れていました:

 cell.imageView.image = image1;
4

5 に答える 5

2

これはあなたが探していた答えではないかもしれませんが、それは URL を読み込むための推奨される方法ではありません。NSURLRequest や NSURLConnection など、利用可能な URL 読み込みクラスを使用する必要があります。

これを試して:

NSURLRequest *imageRequest = [[NSURLRequest alloc] initWithURL:imageURL];
[NSURLConnection sendAsynchronousRequest:imageRequest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    if (!error) {
        UIImage *image = [[UIImage alloc] initWithData:data];
        [imageView setImage:image];
    }
}];
于 2013-04-01T17:16:20.737 に答える
2

iOS の UIElements は、常にメイン スレッドを介して更新する必要があります。あなたができることは: -

   __block NSData *data;
    dispatch_queue_t myQueue = dispatch_queue_create("com.appName", NULL);
    dispatch_async(myQueue, ^{
       data = [NSData dataWithContentsOfURL:imgUrl1];
       dispatch_async(dispatch_get_main_queue(), ^(void) {
       cell.imageView.image = [UIImage imageWithData = data];
    });
    });

または、AFNetworking を使用して URL から画像を取得するより良い方法があります。それはより速く、より簡単です。1行のコードを書くだけです:-

[cell.imageView setImageWithURL:imgUrl1];
于 2013-04-01T17:15:28.707 に答える
1

画像を再描画する必要があることをビューに通知する必要があります。追加:

[imageView setNeedsDisplay];

メソッドの最後までloadImages

于 2013-04-01T17:09:01.230 に答える
1

ここには多くの問題があります:

  1. 実行ループを実行していないスレッドでネットワーク リクエストを開始することはできません。
  2. メイン スレッド以外のスレッドから UI を更新することはできません。
  3. [NSData dataWithContentsOfURL:imgUrl1]別のスレッド (特にメイン スレッド) であっても、外部リソースを安全にロードする方法ではありません。
  4. 別のスレッドにディスパッチするときはいつでも、テーブル セルがリサイクルされて、思っているデータが表示されなくなるリスクがあります。(これはまだ同じセル インスタンスですが、他の行のデータが表示されています。)

あなたがすべきこと:

  1. メインスレッドで非同期呼び出しを使用してネットワーク操作を開始します。(必要に応じて別のスレッドまたはキューを使用できますが、実行ループが実行されていることを確認する必要があります。)
  2. デリゲート メッセージから、別のスレッドで画像のデコードをディスパッチします。
  3. イメージがデコードされたら、メイン スレッドにディスパッチして更新します。
  4. 実際に画像を割り当てる前に、セルがまだ目的に使用されていることを確認してください。

最初の 3 つの問題は、AFNetworkingを使用して解決できます。デリゲート メソッドをラップし、成功と失敗のブロックを提供するだけです。特に、 AFNetworking のAFImageRequestOperationは、前述のようにキュー間でコードをバウンスします。(メインのネットワーク ループを別のスレッドで実行することさえありますが、これは必要ではありません。

セルの ID を確認する必要があります。

于 2013-04-02T06:20:49.243 に答える
0

TableView で使用しているので、[self.tableView reloadData]; を追加します。loadImages メソッドの最後に。

于 2013-04-01T17:33:06.263 に答える