【iOS開(kāi)發(fā)】--UICollectionView復(fù)用的坑

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


image.png

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


image.png

怎么回事?為什么加號(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):


image.png

發(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ù)源方法呢?


image.png

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方法:
image.png

打印結(jié)果:


image.png

經(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的異步圖片
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 技術(shù)無(wú)極限,從菜鳥開(kāi)始,從源碼開(kāi)始。 由于公司目前項(xiàng)目還是用OC寫的項(xiàng)目,沒(méi)有升級(jí)swift 所以暫時(shí)SDWebI...
    充滿活力的早晨閱讀 12,859評(píng)論 0 2
  • ¥開(kāi)啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開(kāi)一個(gè)線程,因...
    小菜c閱讀 7,391評(píng)論 0 17
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,697評(píng)論 1 32
  • 在上一篇文章中,我們已經(jīng)基本完成了模塊加載器的基本功能,接下來(lái)來(lái)完成一下路徑解析的問(wèn)題。 在之前的功能中,我們所有...
    忽如寄閱讀 236評(píng)論 0 1
  • 說(shuō)明1、簡(jiǎn)化了函數(shù)的書寫操作符:輸入的參數(shù)=>進(jìn)行的操作以及返回的值(顛覆了js以往的傳統(tǒng)編碼習(xí)慣)2、注意事項(xiàng):...
    擠時(shí)間學(xué)習(xí)的阿龍閱讀 491評(píng)論 0 0

友情鏈接更多精彩內(nèi)容