1

gcd を使用してバックグラウンドで画像を読み込もうとしています。私の最初の試みはうまくいきませんでした:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0), ^{
  dispatch_async(dispatch_get_main_queue(), ^{
    // create UI Image, add to subview
  });
});

バックグラウンド キュー コードをコメント アウトし、メイン キュー ディスパッチ ブロックだけを残しても機能しませんでした。

dispatch_async(dispatch_get_main_queue(), ^{
  // create UI Image, add to subview
});

gcd ブロック内で ui を行うためのトリックはありますか?

mattjgaloway のコメントに応えて、バックグラウンド スレッドに大きな画像を読み込もうとしているだけです。最初に試した完全なコードは次のとおりです。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0), ^{

    UIImage* img = [[UIImage alloc] initWithContentsOfFile: path];

    dispatch_async(dispatch_get_main_queue(), ^{

       imageView = [[[UIImageView alloc] initWithImage:  img] autorelease];
       imageView.contentMode = UIViewContentModeScaleAspectFill;
       CGRect photoFrame = self.frame;
       imageView.frame = photoFrame;
       [self addSubview:imageView];

  });

});

メインキュー内ですべてを実行するように単純化しましたが、それでも機能しませんでした。メイン キューですべてを機能させることができない場合、バックグラウンド キューが機能する方法はありません。


================ 更新 ==============

上記の手法 (gcd とすべて) を新しいプロジェクトで試してみましたが、実際に期待どおりに機能します。私の現在のプロジェクトではありません。そのため、何がうまくいかないのかを突き止めるために、ゆっくりと苦痛を伴う除去作業を行う必要があります。このバックグラウンド読み込みを使用して、uiscrollview に画像を表示しています。画像の一部が表示されることがありますが、常に表示されるわけではありません。私はこれの底に行きます....

================ 更新 ==============

この問題は UIScrollView に関連しているように見えますが、これはすべて内部にあります。必要なときに描画/更新されていないと思います

4

3 に答える 3

1

setNeedDisplayちなみに、UIKitのほとんどはスレッドセーフではないので、すぐに呼び出してみてください[self addSubview:imageView]。UIImageメソッドについては特にわかりません(iOS4以降では問題ないかもしれません)が、そうはしません。バックグラウンドから画像をロードする場合は、スレッドセーフなImageIOまたはコアグラフィックス関数を使用することをお勧めします。
別の方法として、NSDataオブジェクトに画像データをバックグラウンドスレッドにロードし、後で[UIImage alloc]inithWithData: data]メインスレッドを呼び出すこともできます。

于 2012-05-22T05:22:05.203 に答える
1

私はあなたのコードを実行しました。1 つの例外を除いて動作します。また、self ではなく self.view という意味でしたか?

ケース 1:

path はプロパティで宣言されています。
imageView は ivar で宣言されています

- (IBAction)buttonImagePressed:(id)sender 
{
    self.path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"picture1.jpg"];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0), ^{
        UIImage* img = [[UIImage alloc] initWithContentsOfFile: self.path];  
        dispatch_async(dispatch_get_main_queue(), ^{
            imageView = [[[UIImageView alloc] initWithImage:  img] autorelease];
            imageView.contentMode = UIViewContentModeScaleAspectFill;
            CGRect photoFrame = self.view.frame;
            imageView.frame = photoFrame;
            [self.view addSubview:imageView];
        });
    });
}

ケース 2:

path と imageView はどちらも ivar です。- プロパティは使用されません。

- (IBAction)buttonImagePressed:(id)sender 
{
// will crash if path is defined here
//    path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"picture1.jpg"];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0), ^{
        //if path is defined here then it will work
        path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"picture1.jpg"];
        UIImage* img = [[UIImage alloc] initWithContentsOfFile:path];
        dispatch_async(dispatch_get_main_queue(), ^{
            imageView = [[[UIImageView alloc] initWithImage:  img] autorelease];
            imageView.contentMode = UIViewContentModeScaleAspectFill;
            CGRect photoFrame = self.view.frame;
            imageView.frame = photoFrame;
            [self.view addSubview:imageView];
        });
    });
}

クラッシュしたケース 2 では、コンソールのメッセージは、apple.com でバグを報告するように言っていました ...

于 2012-05-22T02:10:22.843 に答える
0

サブビューとして追加された UIImageView ではなく、背景画像として画像を表示すると機能します。理由がわからない

@interface PhotoView(){
  UIImageView* imageView;
}

@end


@implementation PhotoView

-(id)initWithFrame:(CGRect)frame andPathToPhoto:(NSString*)path andSequenceView:(SequencerView*) sequencerView{
  if(self = [super initWithFrame:frame]){


    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0), ^{
      UIImage* img = [[UIImage alloc] initWithContentsOfFile: path];
      dispatch_async(dispatch_get_main_queue(), ^{
        self.backgroundColor = [UIColor colorWithPatternImage:img];
      });
      [img release];
    });

  }
  return self;
}

@end
于 2012-06-01T20:59:42.930 に答える