mcp*_*njr 11 iphone asynchronous ios nscache
我一直在寻找一种明确的方法来做到这一点,并没有找到任何可以给出一个例子并解释得很好的地方.我希望你能帮助我.
这是我正在使用的代码:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"NewsCell";
NewsCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
NewsItem *item = [newsItemsArray objectAtIndex:indexPath.row];
cell.newsTitle.text = item.title;
NSCache *cache = [_cachedImages objectAtIndex:indexPath.row];
[cache setName:@"image"];
[cache setCountLimit:50];
UIImage *currentImage = [cache objectForKey:@"image"];
if (currentImage) {
NSLog(@"Cached Image Found");
cell.imageView.image = currentImage;
}else {
NSLog(@"No Cached Image");
cell.newsImage.image = nil;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), ^(void)
{
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:item.image]];
dispatch_async(dispatch_get_main_queue(), ^(void)
{
cell.newsImage.image = [UIImage imageWithData:imageData];
[cache setValue:[UIImage imageWithData:imageData] forKey:@"image"];
NSLog(@"Record String = %@",[cache objectForKey:@"image"]);
});
});
}
return cell;
}
Run Code Online (Sandbox Code Playgroud)
缓存为我返回nil.
Rob*_*Rob 15
Nitin回答了关于如何使用缓存的问题.问题是,原始问题和Nitin的答案都存在一个问题,即你正在使用GCD,它(a)不能控制并发请求的数量; (b)派遣的街区不可取消.此外,您正在使用dataWithContentsOfURL,这是不可取消的.
请参阅WWDC 2012视频带块的异步设计模式,GCD和XPC,第7节"分离控制和数据流",大约48分钟进入视频,讨论为什么会出现问题,即如果用户快速向下滚动列表到第100个项目,所有其他99个请求将排队等候.在极端情况下,您可以使用所有可用的工作线程.并且iOS无论如何只允许五个并发网络请求,因此使用所有这些线程没有意义(如果一些调度块启动无法启动的请求,因为有五个以上的请求,一些网络请求将开始失败).
因此,除了当前异步执行网络请求和使用缓存的方法之外,您应该:
使用操作队列,它允许您(a)约束并发请求的数量; 及(b)开启取消营运的能力;
也可以使用可取消的NSURLSession.您可以自己执行此操作,也可以使用AFNetworking或SDWebImage等库.
重复使用单元格时,取消前一个单元格的任何待处理请求(如果有).
这可以完成,我们可以告诉你如何正确地完成它,但它是很多代码.最好的方法是使用许多UIImageView类别中的一个,它们进行缓存,但也处理所有这些其他问题.SDWebImage的UIImageView类别非常好.它大大简化了您的代码:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = @"NewsCell"; // BTW, stay with your standard single cellIdentifier
NewsCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier indexPath:indexPath];
NewsItem *item = newsItemsArray[indexPath.row];
cell.newsTitle.text = item.title;
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:item.image]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
return cell;
}
Run Code Online (Sandbox Code Playgroud)
Nit*_*hel 10
可能你做错了你为每个图像设置相同的密钥 NSCache
[cache setValue:[UIImage imageWithData:imageData] forKey:@"image"];
Run Code Online (Sandbox Code Playgroud)
使用此代替以上设置ForKey作为Imagepath item.image并使用setObject而不是setVlaue: -
[self.imageCache setObject:image forKey:item.image];
Run Code Online (Sandbox Code Playgroud)
尝试使用此代码示例: -
in .h分类: -
@property (nonatomic, strong) NSCache *imageCache;
Run Code Online (Sandbox Code Playgroud)
在.m类: -
- (void)viewDidLoad
{
[super viewDidLoad];
self.imageCache = [[NSCache alloc] init];
// the rest of your viewDidLoad
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"cell";
NewsCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
NewsItem *item = [newsItemsArray objectAtIndex:indexPath.row];
cell.newsTitle.text = item.title;
UIImage *cachedImage = [self.imageCache objectForKey:item.image];;
if (cachedImage)
{
cell.imageView.image = cachedImage;
}
else
{
cell.imageView.image = [UIImage imageNamed:@"blankthumbnail.png"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:item.image]];
UIImage *image = nil;
if (imageData)
image = [UIImage imageWithData:imageData];
if (image)
{
[self.imageCache setObject:image forKey:item.image];
}
dispatch_async(dispatch_get_main_queue(), ^{
UITableViewCell *updateCell = [tableView cellForRowAtIndexPath:indexPath];
if (updateCell)
cell.imageView.image = [UIImage imageWithData:imageData];
NSLog(@"Record String = %@",[cache objectForKey:@"image"]);
});
});
}
return cell;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9117 次 |
| 最近记录: |