【原创】开源中国阅读小记 - 3 - TableCell图片异步加载

来源:互联网 发布:淘宝账户怎么修改名字 编辑:程序博客网 时间:2024/04/29 10:37

首先看TableView获取cell实例的方法

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

涉及Cell实例化的代码:

PostCell *cell = (PostCell *)[tableView dequeueReusableCellWithIdentifier:PostCellIdentifier];            if (!cell)             {                // loadNib 方式加载nib从而实例化自定义Cell                NSArray *objects = [[NSBundle mainBundle] loadNibNamed:@"PostCell" owner:self options:nil];                for (NSObject *o in objects) {                    if([o isKindOfClass:[PostCell class]]){                        cell = (PostCell *)o;                        break;                    }                }                UITap *singleTap = [[UITap alloc] initWithTarget:self action:@selector(clickImg:)];                // 设置手势,当单击头像图片的时候打开用户详细信息页面                [cell.img addGestureRecognizer:singleTap];            }            // 加载默认的图片            cell.img.image = [UIImage imageNamed:@"avatar_loading.jpg"];            Post *p = [posts objectAtIndex:indexPath.row];            if ([cell.img.gestureRecognizers count] > 0) {                UITap *tap = (UITap *)[cell.img.gestureRecognizers objectAtIndex:0];                if (tap) {                    // 给手势设置tag,用以点击的时候能知道需要展开的具体用户(ID)                    tap.tag = p.authorid;                }            }            cell.lbl_answer_chinese.text = self.catalog <= 1 ? @"回答" : @"回帖";            cell.txt_Title.text = p.title;            cell.txt_Title.font = [UIFont boldSystemFontOfSize:14.0];            cell.lbl_AnswerCount.text = [NSString stringWithFormat:@"%d", p.answerCount];            cell.lblAuthor.text = [NSString stringWithFormat:@"%@ 发布于%@", p.author, p.fromNowOn];            if (p.imgData) {                // 将已加载且在内存中的image直接赋值                cell.img.image = p.imgData;            }            else // 图片不再内存中...            {                 if ([p.img isEqualToString:@""]) {                    p.imgData = [UIImage imageNamed:@"avatar_noimg.jpg"];                }                else                {                    // TangQiao ImageCache :)                    // 尝试从内存池中获取图片                    NSData * imageData = [_iconCache getImage:[TQImageCache parseUrlForCacheName:p.img]];                    if (imageData) {                        p.imgData = [UIImage imageWithData:imageData];                        cell.img.image = p.imgData;                    }                     else                     {                        // 判断当前位置的图片是否在读取中,如果在读取中,则downloader不为nil,则忽略(因为网络交互还在进行中)                        IconDownloader *downloader = [imageDownloadsInProgress objectForKey:[NSString stringWithFormat:@"%d", [indexPath row]]];                        if (downloader == nil) {                            // 如果为空,则进行异步读取,并将其加入字典 imageDownloadsInProgress中                            ImgRecord *record = [ImgRecord new];                            record.url = p.img;                            [self startIconDownload:record forIndexPath:indexPath];                        }                    }                }            }            return cell;

下一步,startIconDownload: forIndexPath:中的实现,简要而言,就是做以下几件事:

1. 实例化IconDownloader,并将其set到imageDownloadsInProgress中

2. iconDownloader的实例则使用

NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:                             [NSURLRequest requestWithURL:                              [NSURL URLWithString:imgRecord.url]] delegate:self];

进行异步请求

3. 当conn执行完毕,执行它的delegate - IconDownloader的finish方法,在这个方法中缓存image

4. finish方法中,调用delegate - PostView,将ImageData通过UIImagePNGRepresentation渲染为image(png) data,并调用[tablePosts reloadData]

 

这里,值得商榷的是:每一张图片加载完毕都调用一次reloadData的方式是否是最优?

 

 

原创粉丝点击