2012-03-19 9 views
4

ウェブから画像をダウンロードしてImageViewに表示する必要があります。現在私はSDWebImageを使用しています(これは、キャッシュをサポートする非同期イメージダウンローダで、UIImageViewカテゴリを使用しています)。画像を非同期でダウンロード

しかし、戻るボタンと進むボタンをクリックするとクラッシュする(ビューを繰り返し前後に移動しようとすると)。とにかくこれは非常にまれですが、私はこのバグを取り除く必要があります。自分のプロジェクトで使用できる他のライブラリ(プライベートAPIを使用していないライブラリ)はありますか?

+0

ください。可能であれば、クラッシュログを投稿してください。 –

+0

私の答えを見てください。私が提案したライブラリは完璧に動作します。実装方法がわからない場合はお知らせください。 –

+0

まだ解決されていない場合。 JImage.hを使用するとJImage.mは私が投稿したどのような状況でも助けになります。コピーして貼り付けるだけで自動的に動作します。これは、私が実装していて、画像の読み込みを怠ってもうまく動作する非常に効果的なクラスです(非同期ダウンロード) – Kuldeep

答えて

10

はい:自分のフォトビューコントローラで

- (void)processImageDataWithBlock:(void (^)(NSData *imageData))processImage 
{ 
NSString *url = self.imageURL; 
dispatch_queue_t callerQueue = dispatch_get_current_queue(); 
dispatch_queue_t downloadQueue = dispatch_queue_create("Photo Downloader", NULL); 
dispatch_async(downloadQueue, ^{ 
    NSData *imageData = *insert code that fetches photo from server*; 
    dispatch_async(callerQueue, ^{ 
     processImage(imageData); 
    }); 
}); 
dispatch_release(downloadQueue); 
} 

を、あなたはこのように、この関数を呼び出すことができます。あなたは他のlibaryを利用することができます。私はすでにAsyncImageViewを使用して実装しました。これはUIImageViewから継承されています。それは、URLからフェッチされたキャッシュメモリに画像を保存し、画像を同じURLからロードする必要があるときはいつでも、それをキャッシュメモリからロードして、多くの時間を節約します。私が実装されてきた技術を示す画像を見てください

https://github.com/nicklockwood/AsyncImageView#readme

http://www.markj.net/iphone-asynchronous-table-image/

ちょうどそれを実装するためのリンクをたどってください。画像がロードされている間に他のアクティビティーを行うことができます。:

enter image description here

+0

'AsyncImageView'または 'iphone-asynchronous-table-image'はプライベートAPIを使用していますか?あなたはこれを見てきましたか? – shajem

+0

https://github.com/nicklockwood/AsyncImageView/blob/master/LICENCE.md –

+1

プライベートAPIを使用しているかどうかはわかりません – shajem

6

NSURLConnectionは、非同期ダウンロードを提供し、iOSに組み込まれています。

+0

これはキャッシュサポートのように、SDWebImageより優れたアプローチですか? – shajem

+0

はデータをメモリに格納します。どのようにデータを扱うかによって異なります。 – Bahamut

+1

もう一度やり直す努力を必要とする別の解決策を提案することは問題に答える適切な方法ではありません。今あなたの場所に自分自身を置き、あなたが何をするだろうあなたのすべてのものを再構築する必要があると思う?私たちはクラッシュログを見てそこから助けてください。 –

4

私はあなたが "戻る"ときにまだ実行中の接続の代理人ができるいくつかのオブジェクトをリリースするため、あなたが記述したバグが発生する可能性があると思います。クラッシュを避けるためには、実行中の接続のデリゲートになる可能性のあるオブジェクトを解放する前に接続をキャンセルするか、解除する必要があります。

イメージ非同期ダウンロードのもう1つの代替方法はhttp://allseeing-i.com/ASIHTTPRequest/です。

+0

ASIHTTPRequestはもはや良い選択肢ではありません。ビルドされたクラスが弱すぎる時代に戻って使用するのはいいことでしたが、NSURLConnectionが成長し、ASIHTTPRequestの開発が止まったので、もうこれ以上の方法はありません。 – Ahti

0

私は個人的にはNSURLConnection sendSynchronousRequestを使用し、その周りにGCDラッパーを置くことを好みます。すべてをすっきりと整えます。

2
//JImage.h 

#import <Foundation/Foundation.h> 


@interface JImage : UIImageView { 

    NSURLConnection *connection; 

    NSMutableData* data; 

    UIActivityIndicatorView *ai; 
} 

-(void)initWithImageAtURL:(NSURL*)url; 

@property (nonatomic, retain) NSURLConnection *connection; 

@property (nonatomic, retain) NSMutableData* data; 

@property (nonatomic, retain) UIActivityIndicatorView *ai; 

@end 



//JImage.m 

#import "JImage.h" 

@implementation JImage 
@synthesize ai,connection, data; 

-(void)initWithImageAtURL:(NSURL*)url { 


    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; 

    [self setContentMode:UIViewContentModeScaleToFill]; 

    if (!ai){ 

     [self setAi:[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]]; 

     [ai startAnimating]; 

     [ai setFrame:CGRectMake(27.5, 27.5, 20, 20)]; 

     [ai setColor:[UIColor blackColor]]; 

     [self addSubview:ai]; 
    } 
    NSURLRequest* request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60]; 

    connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];  
} 


- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)incrementalData { 

if (data==nil) data = [[NSMutableData alloc] initWithCapacity:5000]; 

[data appendData:incrementalData]; 

NSNumber *resourceLength = [NSNumber numberWithUnsignedInteger:[data length]]; 

NSLog(@"resourceData length: %d", [resourceLength intValue]); 

} 
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
{ 
    NSLog(@"Connection error..."); 

    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 

    [ai removeFromSuperview]; 

} 
- (void)connectionDidFinishLoading:(NSURLConnection*)theConnection 
{ 
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 

    [self setImage:[UIImage imageWithData: data]]; 

    [ai removeFromSuperview]; 
} 
@end 



//Include the definition in your class where you want to use the image 
-(UIImageView*)downloadImage:(NSURL*)url:(CGRect)frame { 

JImage *photoImage=[[JImage alloc] init]; 

    photoImage.backgroundColor = [UIColor clearColor]; 

    [photoImage setFrame:frame]; 

    [photoImage setContentMode:UIViewContentModeScaleToFill]; 

    [photoImage initWithImageAtURL:url]; 

    return photoImage; 
} 


//How to call the class 

UIImageView *imagV=[self downloadImage:url :rect]; 

//you can call the downloadImage function in looping statement and subview the returned imageview. 
//it will help you in lazy loading of images. 


//Hope this will help 
2

画像をキャッシュするためenormegoによってEGOImageLoadingをチェックしてください。 これはUIImageViewと同じように動作し、HTTPから非同期で画像をダウンロードすることができ、簡単に統合することができます。

+0

プライベートAPIは使用していますか? – shajem

+0

いいえ、プライベートAPIを使用していません –

4

私は個人的にiOSのGrand Central Dispatch機能を使用してサーバーから画像を非同期でダウンロードします。

以下は、自分のアプリケーションの1つでFlickrから写真を取得するために使用したコードです。あなたの画像/写真クラスで

は、このようなものである機能があります。

- (void)viewWillAppear:(BOOL)animated 
{ 
[spinner startAnimating]; 
[self.photo processImageDataWithBlock:^(NSData *imageData) { 
    if (self.view.window) { 
     UIImage *image = [UIImage imageWithData:imageData]; 
     imageView.image = image; 
     imageView.frame = CGRectMake(0, 0, image.size.width, image.size.height); 
     scrollView.contentSize = image.size; 
     [spinner stopAnimating]; 
    } 
}]; 
} 
1

私は、これは非常に古いスレッドです知っているが、最近、私はSDWebImageランダムクラッシュがたくさんあったので、私は私自身の遅延ロードとキャッシュメカニズムを実装する必要がありました。それはかなりうまくいく、私は重い負荷の場合にそれをテストしていない。だからここに私はそれを使用する方法に続いての.hと.mファイルのファイルです:私が使用

// UIImageView+CustomCache.h 
@interface UIImageView(CustomCache) 

-(void)startAsyncDownload:(UIImage*)placeHolderImage imageUrlString:(NSString*)imageUrlString; 
@end 


// UIImageView+CustomCache.m 

#import "UIImageView+CustomCache.h" 

@implementation UIImageView(CustomCache) 

-(void)startAsyncDownload:(UIImage*)placeHolderImage imageUrlString:(NSString*)imageUrlString{ 
    self.image = placeHolderImage; 
    [NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL: 
               [NSURL URLWithString:imageUrlString]] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionHandler){ 
     @autoreleasepool { 
      if (connectionHandler != nil) { 
       NSLog(@"error in downloading description %@",connectionHandler.localizedDescription); 
      } else { 
       ImagesCacheHandler *ref = [ImagesCacheHandler new]; 
       UIImage *imageFromData = [[UIImage alloc] initWithData:data]; 
       if (imageFromData != NULL && imageFromData != nil && data.length > 0) { 
        self.image = imageFromData; 
//custom store to sqlite 
        [ref archiveImage:imageUrlString imageData:data moc:[ref fetchContext]]; 
       } 
      } 
     } 
    }]; 
} 

@end 

そして、私のテーブル内のビュー(私はもちろんUIImageView + CustomCache.hをインポート)

UIImageView *imageViewToLazyLoad = (UIImageView*)[cell viewWithTag:1]; 
[imageViewToLazyLoad startAsyncDownload:[UIImage [email protected]"palce_Holder_Image_name"] imageUrlString:imageUrl]; 
関連する問題