25

UIImageView サブビューを持つ UIView があります。UI をブロックせずに UIImageView に画像を読み込む必要があります。ブロッキング呼び出しは次のようです: UIImage imageNamed:. これが私がこの問題を解決したと思ったものです:

-(void)updateImageViewContent {
    dispatch_async(
        dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        UIImage * img = [UIImage imageNamed:@"background.jpg"];
        dispatch_sync(dispatch_get_main_queue(), ^{
            [[self imageView] setImage:img];
        });
    });
}

画像が小さい (150x100)。

ただし、画像をロードするときに UI はブロックされたままです。何が欠けていますか?

この動作を示す小さなコード サンプルを次に示します。

UIImageView に基づいて新しいクラスを作成し、そのユーザー インタラクションを YES に設定し、UIView に 2 つのインスタンスを追加し、その touchesBegan メソッドを次のように実装します。

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if (self.tag == 1) {
        self.backgroundColor= [UIColor redColor];
    }

    else {
    dispatch_async(dispatch_get_main_queue(), ^{
    [self setImage:[UIImage imageNamed:@"woodenTile.jpg"]];
  });
    [UIView animateWithDuration:0.25 animations:
        ^(){[self setFrame:CGRectInset(self.frame, 50, 50)];}];
    }
}

タグ 1 をこれらの imageView の 1 つに割り当てます。

画像をロードするビューから始めて、2 つのビューをほぼ同時にタップすると、正確には何が起こるでしょうか? 返されるのを待っているため、UI がブロックされ[self setImage:[UIImage imageNamed:@"woodenTile.jpg"]];ますか? もしそうなら、どうすればこれを非同期に行うことができますか?

これは、 ipmccコードを使用したgithubのプロジェクトです

長押ししてからドラッグし、黒い四角の周りに四角形を描きます。私が彼の答えを理解しているように、理論的には、画像が最初にロードされたときに白い選択長方形がブロックされるべきではありませんが、実際にはそうです。

プロジェクトには 2 つの画像が含まれています (1 つは小さい: woodenTile.jpg で、もう 1 つは大きい: bois.jpg)。結果はどちらも同じです。

画像フォーマット

画像が初めて読み込まれるときにUIがブロックされるという問題にこれがどのように関連しているかはよくわかりませんが、PNG画像はUIをブロックせずにデコードされますが、JPG画像はUIをブロックします.

イベントの年表

ステップ0 ステップ1

UIのブロックはここから始まります..

ステップ2

..そしてここで終わります。

ステップ 3

AFネットワーキングソリューション

    NSURL * url =  [ [NSBundle mainBundle]URLForResource:@"bois" withExtension:@"jpg"];
    NSURLRequest * request = [NSURLRequest requestWithURL:url];
    [self.imageView setImageWithURLRequest:request
                          placeholderImage:[UIImage imageNamed:@"placeholder.png"]
                                   success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
                                       NSLog(@"success: %@", NSStringFromCGSize([image size]));
                                   } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
                                       NSLog(@"failure: %@", response);
                                   }];

// this code works. Used to test that url is valid. But it's blocking the UI as expected.
if (false)       
if (url) {
        [self.imageView setImage: [UIImage imageWithData:[NSData dataWithContentsOfURL:url]]]; }

ほとんどの場合、次のログが記録されます。success: {512, 512}

また、時折ログに記録します。success: {0, 0}

そして時折:failure: <NSURLResponse: 0x146c0000> { URL: file:///var/mobile/Appl...

しかし、そのイメージは決して変わりません。

4

11 に答える 11

5

カテゴリをインポートすることにより、 AFNetworkingライブラリを使用できます

「UIImageView+AFNetworking.m」と、次のメソッドを使用して:

[YourImageView setImageWithURL:[NSURL URLWithString:@"http://image_to_download_from_serrver.jpg"] 
      placeholderImage:[UIImage imageNamed:@"static_local_image.png"]
               success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
                  //ON success perform 
               }
               failure:NULL];

お役に立てれば 。

于 2013-10-14T08:02:36.917 に答える
4

アプリケーションで非常によく似た問題が発生し、多くの画像をダウンロードする必要があり、UI が継続的に更新されていました。以下は、私の問題を解決した簡単なチュートリアルのリンクです。

NSOperations & NSOperationQueues チュートリアル

于 2013-10-14T14:56:03.857 に答える
3

これは良い方法です:

-(void)updateImageViewContent {
    dispatch_async(dispatch_get_main_queue(), ^{

        UIImage * img = [UIImage imageNamed:@"background.jpg"];
        [[self imageView] setImage:img];
    });
}
于 2013-10-04T10:41:00.730 に答える
2

AsyncImageViewのようなサードパーティのライブラリを使用しないのはなぜですか? これを使用して、AsyncImageView オブジェクトを宣言し、ロードする URL または画像を渡すだけです。画像の読み込み中にアクティビティ インジケーターが表示され、UI をブロックするものは何もありません。

于 2013-10-04T11:23:03.420 に答える
0

私が実装した1つの方法は次のとおりです:(ただし、それが最適かどうかはわかりません)

最初に、シリアル非同期または並列キューを使用してキューを作成します

queue = dispatch_queue_create("com.myapp.imageProcessingQueue", DISPATCH_QUEUE_SERIAL);**

or

queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0);

**

あなたのニーズに合ったものを見つけることができます。

その後:

 dispatch_async( queue, ^{



            // Load UImage from URL
            // by using ImageWithContentsOfUrl or 

            UIImage *imagename = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];

            // Then to set the image it must be done on the main thread
            dispatch_sync( dispatch_get_main_queue(), ^{
                [page_cover setImage: imagename];
                imagename = nil;
            });

        });
于 2013-10-15T11:48:47.643 に答える
0

アプリケーションで AFNetwork を使用している場合、AFNetwork がソリューションを提供するため、ロード イメージにブロックを使用する必要はありません。以下のように:

#import "UIImageView+AFNetworking.h"

   Use **setImageWithURL** function of AFNetwork....

ありがとう

于 2013-10-15T11:11:42.337 に答える
0

SDWebImageの使用を検討してください。バックグラウンドで画像をダウンロードしてキャッシュするだけでなく、画像をロードしてレンダリングします。

ダウンロードした後でも読み込みが遅い大きな画像を含むテーブルビューで、良い結果で使用しました。

于 2013-10-15T06:15:41.170 に答える