最近項(xiàng)目需要用到UICollectionView顯示網(wǎng)絡(luò)圖片,在寫demo時(shí)遇到一個(gè)BUG我想要這個(gè)效果(最后一個(gè)是加號(hào),點(diǎn)擊進(jìn)入相冊(cè))

這個(gè)很簡(jiǎn)單,很快寫完,運(yùn)行如下圖:

怎么回事?為什么加號(hào)沒(méi)有顯示?
有此BUG的代碼在這里,有想挑戰(zhàn)一下的可以去下載
,解決完了,記得回來(lái)看看。
顯示加號(hào)的邏輯很簡(jiǎn)單,在cellForItemAtIndexPath:數(shù)據(jù)源方法里判斷一下:
CollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CollectionCell" forIndexPath:indexPath];
if (indexPath.item == self.dataSourses.count) {
//顯示加號(hào),隱藏叉號(hào):
cell.image = [UIImage imageNamed:@"123"];
cell.deleteButton.hidden = YES;
} else {
//顯示圖片
cell.model = self.dataSourses[indexPath.item];
}
CollectionCell.m
- (void)setMedia:(Model *)media {
_media = media;
[self.imageV sd_setImageWithURL:[NSURL URLWithString:media.imagUrl]];
}
賦值圖片的時(shí)候,很簡(jiǎn)單的用了SD,不應(yīng)該有問(wèn)題啊,通過(guò)觀察可知,貌似是因?yàn)閺?fù)用的問(wèn)題。
在此先給出此問(wèn)題的解決方法:
解法1:在reload的時(shí)候不要加異步主線程(此方法不推薦)
//dispatch_async(dispatch_get_main_queue(), ^{
[self.collectionView reloadData];
// });
解法2:在賦值dataSourses地方加延遲
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
collectionV.dataSources = @[
@"http://pic32.nipic.com/20130823/13339320_183302468194_2.jpg",
@"http://pic40.nipic.com/20140412/18428321_144447597175_2.jpg",
@"http://k.zol-img.com.cn/sjbbs/7692/a7691515_s.jpg"];
});
解法3:讓reloadData方法在SD的線程安全宏里執(zhí)行
dispatch_main_async_safe(^{
[self.collectionView reloadData];
);
解法4:cellForItemAtIndexPath里的代碼加一行代碼
CollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CollectionCell" forIndexPath:indexPath];
if (indexPath.item == self.dataSourses.count) {
cell.imageV sd_cancelCurrentImageLoad];//加上此行代碼
//顯示加號(hào),隱藏叉號(hào):
cell.image = [UIImage imageNamed:@"123"];
cell.deleteButton.hidden = YES;
} else {
//顯示圖片
cell.model = self.dataSourses[indexPath.item];
}
分析過(guò)程:
1 在cellForItemAtIndexPath方法里的打斷點(diǎn):

發(fā)現(xiàn)執(zhí)行過(guò)程沒(méi)有太大問(wèn)題,有個(gè)小問(wèn)題是方法走了 2*4=8次;也就是說(shuō)有兩次reloadData的過(guò)程。
2 在reload方法里打個(gè)斷點(diǎn),發(fā)現(xiàn)只執(zhí)行了一次,那為什么執(zhí)行兩遍數(shù)據(jù)源方法呢?

3 得出結(jié)論系統(tǒng)會(huì)隱式調(diào)用一遍數(shù)據(jù)源方法
4 到這里還是沒(méi)有找打問(wèn)題的原因,既然imageview有問(wèn)題,那我就看一下imageview的setImage方法執(zhí)行的細(xì)節(jié),我把cell中的imageV換成了繼承與UIImageView的LQImageView,重寫了setImage方法:

打印結(jié)果:

經(jīng)過(guò)分析得出結(jié)論:
兩次reload的 加號(hào)的那個(gè)cell有問(wèn)題,reload2 覆蓋了reload1 的所有圖片,除了reload2
的加號(hào),因?yàn)閞eload2的加號(hào)cell是直接setImage了,隨后SD異步圖片回來(lái)了,又賦值一次,
這個(gè)圖片是reload1的異步圖片