缓存UITableViewCells

时间:2014-08-26 15:39:34

标签: ios objective-c uitableview caching

我有一个UITableView的视图,其中可以显示4种UITableViewCell个(自定义的)。基本上,其中两个是媒体(图像,移动,声音),其中2个还有用户头像。

让我们概括一下,带媒体的单元格只会显示图像(缩略图)。当然,在创建单元格时动态下载这些图像。每次用户滚动表格视图时下载这些图像都是有害的,所以我使用EGOCache来缓存这些图像,但是...... 这不能帮助滚动问题!! I我认为缓存会将pionter存储到这些图像中,但每次重新创建单元格时都会从磁盘中获取此图像(因此Intruments告诉我这种方法会影响我的性能)。

我的问题是:如何缓存UITableViewCell以便每次滚动UITableView时都不会创建它?


以下是我的代码中的示例,因此您可以想象我的问题:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    Event *event = [self.events objectAtIndex:indexPath.row];

    if ([event.type isEqualToString:@"camp"]) {
        if (!event.mediaType) {
            CampCell *cell = [self.tableView dequeueReusableCellWithIdentifier:[CampCell identifier]];
            [cell configureWithModel:event];
            return cell;
        } else {
            CampMediaCell *cell = [self.tableView dequeueReusableCellWithIdentifier:[CampMediaCell identifier]];
            [cell configureWithModel:event];
            return cell;
        }
    } else {
        if (!event.mediaType) {
            StatusCell * cell = [self.tableView dequeueReusableCellWithIdentifier:[StatusCell identifier]];
            [cell configureWithModel:event];
            return cell;
        } else {
            StatusMediaCell *cell = [self.tableView dequeueReusableCellWithIdentifier:[StatusMediaCell identifier]];
            [cell configureWithModel:event];
            return cell;
        }
    }
}

这就是configureWithModel:的样子:

- (void)configureWithModel:(id)model {
    if ([model isKindOfClass:[Event class]]) {
        Event *event = model;
        self.titleLabel.text = event.title;
        self.locationLabel.text = event.address;
        self.timeLabel.text = [self hoursLeftToDate:event.expirationDate];

        UIImageView *imageAttachedToStatus = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.mediaContainerView.frame.size.width, self.mediaContainerView.frame.size.height)];
        imageAttachedToStatus.contentMode = UIViewContentModeScaleAspectFill;
        imageAttachedToStatus.clipsToBounds = YES;

        [self getMediaAttachmentForModel:model completion:^(id attachment) {
            if (attachment) {
                imageAttachedToStatus.image = (UIImage *)attachment;
            }
        }];

        [self.mediaContainerView addSubview:imageAttachedToStatus];
    }
}

当然,你可能想知道getMediaAttachmentForModel:completion:是怎样的......

- (void)getMediaAttachmentForModel:(Event *)model completion:(void (^)(id attachment))completion {
    NSString *mediaID = [NSString stringWithFormat:@"media%li", (long)model.eventID];

    if ([[EGOCache globalCache] hasCacheForKey:mediaID]) {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            id cachedAttachment =[[EGOCache globalCache] objectForKey:mediaID];
            dispatch_async(dispatch_get_main_queue(), ^{
                completion(cachedAttachment);
            });
        });
    } else {
        [[Client sharedClient] fetchMediaThumbnailForEvent:model completion:^(id attachment, NSError *error) {
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                [[EGOCache globalCache] setObject:attachment forKey:mediaID];

                dispatch_async(dispatch_get_main_queue(), ^{
                    completion(attachment);
                });
            });
        }];
    }
}

1 个答案:

答案 0 :(得分:0)

正确的解决方案是找到/实现一个能够在内存中缓存图像的缓存,而不是每次都从磁盘中获取它们。

看一下Path的FastImageCache