xcode async tableview加载图片移动listview图片消失了

时间:2013-12-16 15:00:31

标签: objective-c uitableview asynchronous loadimage

我们想要将图像和数据异步下载到我们的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

1 个答案:

答案 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;
}