在后台加载图像以优化ios中的加载
我试图优化我的应用程序的负载,实际上,我有很多图像加载在我的应用程序,我花了很多时间等待视图控制器打开,特别是第一个初始视图,其中包括很多的图像。
我看了一下苹果样品
但我不能重新工作整个应用程序,我想要的只是具体告诉我该怎么办?
在tableview
,cell的实现cellforrowatindexpath:
NSURL *imageURL = ......; NSData *imageData = [NSData dataWithContentsOfURL:imageURL]; UIImage *imageLoad; imageLoad = [[UIImage alloc] initWithData:imageData]; imageView.image = imageLoad;
我可以做些什么吗?
感谢您的帮助!
是的,你可以添加占位符图像。
它不会减慢滚动速度,并随着时间的推移加载图像。
还导入这个文件UIImageView + WebCache.m和MapKit框架
这里是下载文件的链接 。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; } UIImageview* iV = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 50, 50)]; [iV setImageWithURL:[NSURL URLWithString:url] placeholderImage:[UIImage imageNamed:@"image_placeholder.gif"]]; [cell.contentView addSubview:iV]; [iV release]; }
只要清理,build立和运行。
试试这个代码:
dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); dispatch_async(q, ^{ /* Fetch the image from the server... */ NSData *data = [NSData dataWithContentsOfURL:url]; UIImage *img = [[UIImage alloc] initWithData:data]; dispatch_async(dispatch_get_main_queue(), ^{ /* This is the main thread again, where we set the tableView's image to be what we just fetched. */ cell.imgview.image = img; }); });
在从服务器获取图像时启用应用程序,并在加载图像时禁用块尝试使用UIImageView + AFNetworking库asynchronous加载服务器的图像AFNetworking
NSString *imageUrl = [[dict objectForKey:@"photo"] objectForKey:@"url"]; UIImageView *myImage = [[UIImageView alloc] init]; [myImage setImageWithURL:[NSURL URLWithString:imageUrl] placeholderImage:[UIImage imageNamed:@"PlaceHolder.png"]];
只需添加这个库,并包含UIImageView + AFNetworking,以便您可以使用新的UIImageView类别imageWithUrl
看看这个控制: https : //github.com/nicklockwood/AsyncImageView
这很容易实现(只有1个头文件),并将适合您的需要就好了。
使用此控件:而不是声明:
NSURL *imageURL = ......; NSData *imageData = [NSData dataWithContentsOfURL:imageURL]; UIImage *imageLoad; imageLoad = [[UIImage alloc] initWithData:imageData]; imageView.image = imageLoad;
使用:
NSURL *imageURL = ......; imageView.imageURL = imageURL;
你可以查看NSOperationQueue上的这个教程,这个在GCD上完全一样。 你也可以尝试使用:
// Block variable to be assigned in block. __block NSData *imageData; dispatch_queue_t backgroundQueue = dispatch_queue_create("com.razeware.imagegrabber.bgqueue", NULL); // Dispatch a background thread for download dispatch_async(backgroundQueue, ^(void) { imageData = [NSData dataWithContentsOfURL:imageURL]; UIImage *imageLoad; imageLoad = [[UIImage alloc] initWithData:imageData]; // Update UI on main thread dispatch_async(dispatch_get_main_queue(), ^(void) { imageView.image = imageLoad; }); });
你可以尝试这样的事情!
dispatch_queue_t checkInQueueForPostImage = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); dispatch_async(checkInQueueForPostImage, ^{ UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:postAndCheckInDetails.postImageURL]]]; dispatch_sync(dispatch_get_main_queue(), ^{ if (image!=nil) { [uploadImage setImage:image]; } [cell setNeedsLayout]; }); });
这里是一个略有修改的方法Ramu Pasupoletis的答案。 我添加了__block修饰符,使var img在主线程中调用的块内可见。 这里是我使用的完整的方法定义
-(UITableViewCell*)cellforRowAtIndexPath:(UIIndexPath*)indexPath;
懒惰地提取缩略图。 我还为单元格UIImageView添加了占位符。
//lazy loading of thumbnails for images in cell via bg thread -(void)loadImageForCell:(CustomEditTableViewCell*)theCell withFilepath: (NSString*)filepath{ dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); dispatch_async(q, ^{ UIImage (__block *img) = [UIImage imageWithContentsOfFile:filepath]; UIImage *thumbnail = [[GlobalFunctions sharedGlobalFunctions] imageOfSize:CGSizeMake(40, 40) fromImage:img]; dispatch_async(dispatch_get_main_queue(), ^{ theCell.imageView.image = thumbnail; }); }); }
使用IDAsyncImageView.h
////////////////////////////////////// IDAsyncImageView.h ///////////////////////////////////// @interface IDAsyncImageView : NSObject @property (nonatomic, strong) NSCache *cache; + (instancetype)instance; - (void)loadImageView:(UIImageView*)imageView withURLString:(NSString *)urlString; @end ////////////////////////////////////// IDAsyncImageView.m ///////////////////////////////////// #import "IDAsyncImageView.h" @implementation IDAsyncImageView + (instancetype)instance { static IDAsyncImageView *_instance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [[self alloc] init]; }); return _instance; } - (instancetype)init { self = [super init]; if (self) { self.cache = [[NSCache alloc] init]; } return self; } - (void)loadImageView:(UIImageView*)imageView withURLString:(NSString *)urlString { UIActivityIndicatorView* activityView; activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; activityView.hidesWhenStopped = YES; activityView.center = CGPointMake(imageView.bounds.size.width / 2.0f, imageView.bounds.size.height / 2.0f); activityView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin; [imageView addSubview:activityView]; [activityView startAnimating]; UIImage* imageLoad = [self.cache objectForKey:urlString]; if (nil != imageLoad) { imageView.image = imageLoad; [activityView removeFromSuperview]; } else { // Block variable to be assigned in block. __block NSData *imageData; // Dispatch a background thread for download dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]]; UIImage* imageLoad = [[UIImage alloc] initWithData:imageData]; // Update UI on main thread dispatch_async(dispatch_get_main_queue(), ^(void) { [self.cache setObject:imageLoad forKey:urlString]; imageView.image = imageLoad; [activityView removeFromSuperview]; }); }); } } ////////////////////////////////////// ViewController.m ////////////////////////////////////// - (void)viewDidLoad { [super viewDidLoad]; [[IDAsyncImageView instance] loadImageView:myImageView withURLString:aUrl]; }
您可以使用asynchronousimageview。
- (void) loadImageFromURL:(NSURL*)url placeholderImage:(UIImage*)placeholder cachingKey:(NSString*)key { self.imageURL = url; self.image = placeholder; NSData *cachedData = [FTWCache objectForKey:key]; if (cachedData) { self.imageURL = nil; self.image = [UIImage imageWithData:cachedData]; return; } dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); dispatch_async(queue, ^{ NSData *data = [NSData dataWithContentsOfURL:url]; UIImage *imageFromData = [UIImage imageWithData:data]; [FTWCache setObject:data forKey:key]; if (imageFromData) { if ([self.imageURL.absoluteString isEqualToString:url.absoluteString]) { dispatch_sync(dispatch_get_main_queue(), ^{ self.image = imageFromData; }); } else { // NSLog(@"urls are not the same, bailing out!"); } } self.imageURL = nil; }); }
看看这个链接 。你会有一个使用asynchronousimageview的想法。