简体   繁体   中英

Caching UITableViewCells

I have a view with UITableView in it which can display 4 typles of UITableViewCell 's (custom ones). Basically, two of them are with media (image, move, sound) and 2 of them have additionally users avatars.

Let's generalize that cells with media will display only images (thumbnails). Of course those images are dynamically downloaded when cell is created. It could be harmful to download those images everytime user scrolls the table view so I use EGOCache to cache those images but... This ain't helping with scrolling issues!! I thought that caching will store pionter to those images but everytime cell is recreated it takes this image from disk (so Intruments are telling me that this method is killing my performace).

My question is: How to cache UITableViewCell so it's not created everytime I scroll UITableView a little bit?


Here are samples from my code so you can imagine point of my question:

- (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;
        }
    }
}

And this is how configureWithModel: looks like:

- (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];
    }
}

And, of course, you may wonder how getMediaAttachmentForModel:completion: looks like...

- (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);
                });
            });
        }];
    }
}

The proper solution would be to find/implement a cache that is able to cache images in memory, without fetching them from disk every time.

Take a look at Path's FastImageCache

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM