我们想要将图像和数据异步下载到我们的tableview,我们想要缓存它不再下载它。我们找到了一个缓存代码。这是我们的代码。它是异步工作但当我们滚动表视图时,图像消失并返回(我们暂时看不到图像)。有时错误的图像会出现错误的细胞。可能是什么原因以及我们如何解决?
NSURL *imageURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@",[userInfo[0] serverUrl],[estateList[indexPath.row] imgUrl]]];
NSString *key = [imageURL absoluteString];
NSData *data = [FTWCache objectForKey:key];
if (data) {
UIImage *image = [UIImage imageWithData:data];
cell.imageView.image = image;
} else {
cell.imageView.image = [UIImage imageNamed:@"yukleniyor"];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSData *data = [NSData dataWithContentsOfURL:imageURL];
[FTWCache setObject:data forKey:key];
UIImage *image = [UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
cell.imageView.image = image;
});
});
}
以下是我们找到的用于缓存的代码
标题是这样的
#import <Foundation/Foundation.h>
@interface FTWCache : NSObject
+ (void) resetCache;
+ (void) setObject:(NSData*)data forKey:(NSString*)key;
+ (id) objectForKey:(NSString*)key;
@end
.m文件就像这样
#import "FTWCache.h"
static NSTimeInterval cacheTime = (double)604800;
@implementation FTWCache
+ (void) resetCache {
[[NSFileManager defaultManager] removeItemAtPath:[FTWCache cacheDirectory] error:nil];
}
+ (NSString*) cacheDirectory {
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cacheDirectory = [paths objectAtIndex:0];
cacheDirectory = [cacheDirectory stringByAppendingPathComponent:@"FTWCaches"];
return cacheDirectory;
}
+ (NSData*) objectForKey:(NSString*)key {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *filename = [self.cacheDirectory stringByAppendingPathComponent:key];
if ([fileManager fileExistsAtPath:filename])
{
NSDate *modificationDate = [[fileManager attributesOfItemAtPath:filename error:nil] objectForKey:NSFileModificationDate];
if ([modificationDate timeIntervalSinceNow] > cacheTime) {
[fileManager removeItemAtPath:filename error:nil];
} else {
NSData *data = [NSData dataWithContentsOfFile:filename];
return data;
}
}
return nil;
}
+ (void) setObject:(NSData*)data forKey:(NSString*)key {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *filename = [self.cacheDirectory stringByAppendingPathComponent:key];
BOOL isDir = YES;
if (![fileManager fileExistsAtPath:self.cacheDirectory isDirectory:&isDir]) {
[fileManager createDirectoryAtPath:self.cacheDirectory withIntermediateDirectories:NO attributes:nil error:nil];
}
NSError *error;
@try {
[data writeToFile:filename options:NSDataWritingAtomic error:&error];
}
@catch (NSException * e) {
//TODO: error handling maybe
}
}
@end
答案 0 :(得分:0)
对不起我之前的回答。 我会尝试解释这个问题: 我们有TableView显示的保留区域的总行数和行数。因此,具有异步加载的图像无法加载到其单元格中(因为它是从内存中下载时插入的。)
解决方案非常简单,您必须为每个ImageView分配密钥,并将此密钥与表格的单元格相关联。
我使用此git(https://gist.github.com/khanlou/4998479)
中的代码解决了这个问题上面有两个文件
UIImageView+Network.h
UIImageView+Network.m
您必须将它们包含在项目中,或创建自己的类并粘贴到其中。
此类使用来自(https://github.com/FTW/FTWCache/tree/master/FTWCache)的FTW / FTWCache。所以你也必须将这个项目添加到你的项目中。
之后你必须导入
#import "UIImageView+Network.h"
在文件中,它将使用异步图像加载和缓存。
使用TableView使用
的短代码- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = @"MyTableCell";
MyTableCell *cell = (MyTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil){
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"MyTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
// construction to call method
// [cell.imageView loadImageFromURL:(NSURL*)url placeholderImage:(UIImage*)placeholder cachingKey:(NSString*)key ];
[cell.thumbnailImageView loadImageFromURL:(NSURL*)url placeholderImage:[UIImage imageNamed:@"no_foto.gif"] cachingKey:(NSString*)[NSString stringWithFormat:@"%d",indexPath.row]];
return cell;
}