2

我想從文檔目錄加載圖像到UICollectionView。它的工作原理:平穩,快速....(大聲笑)。但我得到一個問題:當我打電話[collectionView reloadData],圖像閃爍(一次)。這裏是我的代碼:從文檔目錄異步加載圖像到UICollectionView

- (UICollectionViewCell*)collectionView:(UICollectionView *)collectionView_ cellForItemAtIndexPath:(NSIndexPath *)indexPath { 
    NSString *cellIdentifier = NSStringFromClass([AFMyRecentCollectionViewCell class]); 
    AFMyRecentCollectionViewCell *cell = (AFMyRecentCollectionViewCell*)[collectionView_ dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath]; 
    AFMyRecentObject *recent = [[AFRecentManager sharedInstance].arrayRecent objectAtIndex:indexPath.row]; 

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
    dispatch_async(queue, ^{ 
     UIImage *image; 
     NSFileManager *fileManager = [NSFileManager defaultManager]; 
     NSString *filePath = [self databasePathWithPathComponent:[NSString stringWithFormat:@"%@.jpg", recent.id_film]]; 
     if ([fileManager fileExistsAtPath:filePath] == YES) { 
      image = [UIImage imageWithContentsOfFile:filePath]; 
     } 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      if (image) { 
       cell.imageView.image = image; 
      } else { 
       cell.imageView.image = [UIImage imageNamed:@"loadding.png"]; 
      } 
     }); 
    }); 

    cell.layer.shouldRasterize = YES; 
    cell.layer.rasterizationScale = [UIScreen mainScreen].scale; 

    return cell; 
} 

- (NSString *)databasePathWithPathComponent:(NSString*)pathComponent { 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex: 0]; 
    NSString *path = [documentsDirectory stringByAppendingPathComponent:pathComponent]; 
    return path; 
} 
+0

順便說一句,你在技術上應該確保了'cell'還沒有被重新用於另一個'NSIndexPath' 'UIImage'被實例化的時間。很可能,因爲你從本地存儲中檢索,這不太可能是個問題,但是如果你要發起任何網絡請求,那麼在蜂窩網絡上快速滾動時突然變成一個非常實際的問題。因此,要非常小心地使用上述模式,除非您確信在異步更新過程中單元格不能重新使用。 – Rob

回答

1

我面臨flickring &解決它使用以下方法圖像的同樣的問題。

應用相同的延遲加載概念。像創建一個字典對象來存儲顯示之前的所有圖像,在從文檔目錄獲取圖像之前,檢查字典中是否存在圖像,如果它存在,則使用該圖像來顯示它。

如果圖像不在字典中,那麼做數據庫操作。

希望這可以解決您的問題。

+0

感謝您的評論。有用。 – TienLe

+1

如果你這樣做,我會推薦(a)'NSCache'而不是字典;和(b)確保你在接收到內存警告時清除這個數據結構。還要注意,這並沒有達到問題的根源,即在啓動異步調用之前未能初始化'image'屬性。 – Rob

+0

@Rob:我還沒有使用過NSCache。我會嘗試使用它。感謝您的支持。 – TienLe

1

問題是,您正在啓動圖像視圖的異步更新,但是如果單元格被重用,您將在那裏看到舊圖像。因此,在您檢索圖像之前dispatch_async,請確保您先將cell.imageView.image設置爲nil。因此,請確保在啓動正確圖像的異步檢索之前,您不會在單元格中看到之前的圖像。

3

你必須放置和默認/圖像佔位符,以防止..

// this prevents the flicker/blinks 
    cell.imageView.image = nil; // if you dont have any image as placeholder 

    //since you have 
    cell.imageView.image = [UIImage imageNamed:@"loadding.png"]; // this i assume your placeholder image? 

    dispatch_async(queue, ^{ 
     //your codes.. 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      // your codes.. 
     }); 
    });