asynchronous下载图片

我需要从网上下载图像并将其显示在ImageView 。 目前我正在使用SDWebImage (这是一个具有caching支持的asynchronous图像下载器,具有UIImageView类别)。

但是,当我点击后退button和前进button时(当我试图重复来回查看视图时),它会崩溃。 无论如何,这很less发生,但我需要摆脱这个错误。 是否有任何其他库(不使用私有API),我可以在我的项目中使用?

是。 你可以用其他库文件。 我已经实现了使用从UIImageViewinheritance的AsyncImageView 。 它所做的是将图像存储在从URL中获取的高速缓冲存储器中,无论何时需要从同一个 URL再次加载图像,只需从高速缓冲存储器中加载图像就可以节省大量时间。

只需按照以下链接执行:

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

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

请看看我已经实现的技术的图像。 它可以让你做其他活动,而图像加载:

在这里输入图像说明

NSURLConnection提供asynchronous下载,并内置到iOS中。

我认为你描述的错误可能会发生,因为当你“回去”释放一些对象,可以是仍然在运行的连接的委托。 为了避免崩溃,您应该在释放或取消分配任何可能成为正在运行的连接的委托的对象之前取消连接。

图片asynchronous下载的另一种select是http://allseeing-i.com/ASIHTTPRequest/

我个人使用iOS中内置的Grand Central Dispatchfunction来asynchronous下载服务器中的图像。

以下是我用于从我的应用程序中的Flickr获取照片的代码。

在你的图片/照片类,有一个这样的function:

 - (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); } 

在你的Photo View Controller中,你可以像这样调用这个函数:

 - (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]; } }]; } 

通过enormego检查EGOImageLoadingcaching图像。 它像UIImageView一样工作,可以让你从HTTP下载图像asynchronous,而且易于集成

 //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 

我知道这是一个非常老的线程,但最近我有很多与SDWebImage随机崩溃,所以我不得不实现我自己的延迟加载和caching机制。 它工作得很好,我只是没有在重载情况下testing它。 所以这里是.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 imageNamed@"palce_Holder_Image_name"] imageUrlString:imageUrl]; 

我个人更喜欢使用NSURLConnection sendSynchronousRequest并在其周围放置一个GCD包装器。 保持一切整齐。