我正在尝试优化我的应用程序中的负载,事实上,我在应用程序中加载了很多图像,并且我花了很多时间等待视图控制器打开,尤其是第一个初始视图包括很多图像。
我看了apple sample
但我不能重新整理整个应用程序,我想要的只是告诉我具体应该怎么做?我实施了吗?
tableview
中实施单元格cellforrowatindexpath:
的
NSURL *imageURL = ......;
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage *imageLoad;
imageLoad = [[UIImage alloc] initWithData:imageData];
imageView.image = imageLoad;
我可以做些什么吗?
谢谢你的帮助!
答案 0 :(得分:6)
试试这段代码:
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;
});
});
答案 1 :(得分:3)
是的,您可以添加占位符图片。
它不会减慢滚动速度,并会随着时间的推移相应地加载图像。
导入此文件 UIImageView + WebCache.m 和 MapKit 框架
Here is the link下载文件。
- (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];
}
只需清理,构建并运行。
答案 2 :(得分:2)
看看这个控件: 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;
答案 3 :(得分:2)
要在从服务器获取图像时启用应用程序并在加载图像时禁用块,请尝试使用 UIImageView + AFNetworking 库以异步方式从服务器加载图像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
答案 4 :(得分:2)
您可以在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;
});
});
答案 5 :(得分:0)
你可以尝试这样的事情!....
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];
});
});
答案 6 :(得分:0)
您可以使用异步imageview。
- (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;
});
}
看看this link。您将了解如何使用异步imageview。
答案 7 :(得分:0)
以下是Ramu Pasupoletis回答的略微修改方法。我加了 __块 修饰符使var img在主线程上调用的块内可见。这是我在
中使用的完整方法定义-(UITableViewCell*)cellforRowAtIndexPath:(UIIndexPath*)indexPath;
懒洋洋地获取缩略图。我还在那里为细胞UIImageViews添加了占位符。
//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;
});
});
}
答案 8 :(得分:0)
使用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];
}