#import <SDWebImage/UIImageView+WebCache.h> ... - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *MyIdentifier = @"MyIdentifier"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease]; } // Here we use the new provided sd_setImageWithURL: method to load the web image [cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder.png"]]; cell.textLabel.text = @"My Text"; return cell; }
The SDWebImageManager is the class behind the UIImageView+WebCache category. It ties the asynchronous downloader with the image cache store. You can use this class directly to benefit from web image downloading with caching in another context than a UIView (ie: with Cocoa).前端
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/userManager/0.png"]; //SDWebImageManager管理器继承与UIImageView+WedCache。已异步的方式进行下载图片到缓冲区。 SDWebImageManager *manager = [SDWebImageManager sharedManager]; [manager downloadImageWithURL:url options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) { NSLog(@"%ld,%ld",receivedSize,expectedSize); } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { //为imageView设置图片为下载的图片 [self.imageView setImage:image]; //打印图片的来源 NSLog(@"%@",imageURL); }];
It's also possible to use the async image downloader independently:web
[SDWebImageDownloader.sharedDownloader downloadImageWithURL:imageURL options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) { // progression tracking code } completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) { if (image && finished) { // do something with image } }];
在本身的案例中使用SDWebImage代码段:缓存
添加自定义的只读缓存路径,其中这是可选的,若是没有指定,系统会默认 #import "SDWebImage/SDImageCache.h" #import "AppDelegate.h" ...... - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //添加自定义的只读缓存路径:可选的 NSString *bundledPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"CustomPathImages"]; [[SDImageCache sharedImageCache] addReadOnlyCachePath:bundledPath]; ...... }
在使用缓存时,若是内存不够使用时,须要进行清理以释放内存。app
#import "MasterViewController.h" #import "SDWebImage/UIImageView+WebCache.h" ...... //清理缓存, - (void)flushCache { /** * 一、SDImageCache是怎么作数据管理的? SDImageCache分两个部分,一个是内存层面的,一个是硬盘层面的。 内存层面的至关是个缓存器,以Key-Value的形式存储图片。 */ //清理内存缓存 [SDWebImageManager.sharedManager.imageCache clearMemory]; //清理硬盘缓存 [SDWebImageManager.sharedManager.imageCache clearDisk]; } //支持屏幕旋转 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); }
......
//为了显示大图片,替将链接中small替换成source;dom
NSString *largeImageURL = [[_objects objectAtIndex:indexPath.row] stringByReplacingOccurrencesOfString:@"small" withString:@"source"];异步
......async
仪表器的使用方法。ide
#import "DetailViewController.h" #import "SDWebImage/UIImageView+WebCache.h" ...... - (void)configureView { if (self.imageURL) { //建立仪表器 __block UIActivityIndicatorView *activityIndicator; //为防止循环引用问题,因此在block中使用imageView时要设置成弱引用,imageView中使用block,在block中若是再调用imageView时,不设置为弱引用,会出现循环引用问题。 __weak UIImageView *weakImageView = self.imageView; [self.imageView sd_setImageWithURL:self.imageURL placeholderImage:nil options:SDWebImageProgressiveDownload progress:^(NSInteger receivedSize, NSInteger expectedSize) { //检测是否已经存在啦!,若是没有在新建立出一个 if (!activityIndicator) { //将新建立的仪表器添加到imageView视图中 [weakImageView addSubview:activityIndicator = [UIActivityIndicatorView.alloc initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]]; activityIndicator.center = weakImageView.center; //开启动画,转吧!小宇宙 [activityIndicator startAnimating]; } } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL){ //将仪表器从imageView视图中进行删除 [activityIndicator removeFromSuperview]; activityIndicator = nil; }]; } } ......
在Cell中使用异步图片下载。函数
#import "MasterViewController.h" #import "SDWebImage/UIImageView+WebCache.h" ...... /** * 参数解析: 1.获取图片的路径 2.设置占位图片 3.options选项:当indexPath.row为0时,执行 SDWebImageRefreshCached:刷新缓存 */ [cell.imageView sd_setImageWithURL:[NSURL URLWithString:[_objects objectAtIndex:indexPath.row]] placeholderImage:[UIImage imageNamed:@"placeholder"] options:indexPath.row == 0 ? SDWebImageRefreshCached : 0]; ......
在上段代码中,有以下两行代码: fetch
__weak UIImageView *weakImageView = self.imageView;
__block UIActivityIndicatorView *activityIndicator;
其中第一条为了不循环引用问题,加上了__weak,第二条使用了block。如今补充一下循环引用、block的知识点:
循环引用
全部的引用计数系统,都存在循环应用的问题。例以下面的引用关系:
1)对象a建立并引用到了对象b.
2)对象b建立并引用到了对象c.
3)对象c建立并引用到了对象b.
这时候b和c的引用计数分别是2和1。当a再也不使用b,调用release释放对b的全部权,由于c还引用了b,因此b的引用计数为1,
b不会被释放。b不释放,c的引用计数就是1,c也不会被释放。今后,b和c永远留在内存中。这种状况,必须打断循环引用
经过其余规则来维护引用关系。好比,咱们常见的delegate每每是assign方式的属性而不是retain方式 的属性,
赋值不会增长引用计数,就是为了防止delegation两端产生没必要要的循环引用。若是一个UITableViewController对象a
经过retain获取了UITableView对象b的全部权,这个UITableView对象b的delegate又是a,若是这个delegate是retain方式的,
那基本上就没有机会释放这两个对象了。本身在设计使用delegate模式时,也要注意这点。
Block
是能够获取其余函数局部变量的匿名函数,其不但方便开发,而且能够大幅提升应用的执行效率(多核心CPU可直接处理Block指令),若是但愿进行修改局部变量的值,能够在定义局部变量以前使用__block。