2012-12-13 96 views
7

我很新的Objective-C,所以希望這一切都有道理。我從服務器下載了圖像,並在collectionView cellForItemAtIndexPath:方法的圖像視圖中顯示了它們。我面臨的問題是圖像看起來不是緩存。它看起來像每次單元被重用時,服務器的相關圖像正在被重新下載。緩存圖像和UICollectionView

在我viewDidLoad方法中,我創建的NSMutableDictionary:

imageDictionary = [[NSMutableDictionary alloc]initWithCapacity:50.0]; 

從閱讀文件和尋找答案我認爲這類似的問題,再加上下面的代碼就足夠了。我已經在這裏待了幾天,我知道我缺少一些東西,或者我沒有抓住一個概念。

#pragma mark - UICollectionView Data Source 
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section;{ 
    NSLog(@"Begin retrieving photos"); 
    return [self.photos count]; 
} 

-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{ 
    return 1; 
} 

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;{ 
    CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MY_CELL" forIndexPath:indexPath]; 
    cell.imageView.image = nil; 

    if (cell.imageView.image == nil) { 
    dispatch_queue_t downloadQueue = dispatch_queue_create("image downloader", NULL); 
    dispatch_async(downloadQueue, ^{ 
     NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[[self.photos objectAtIndex:indexPath.row] objectForKey:@"fullimage"]]]; 
     UIImage *image = [UIImage imageWithData:data]; 
     [imageDictionary setObject:image forKey:@"Image"]; 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      cell.imageView.image = [imageDictionary objectForKey:@"Image"]; 
      [cell setNeedsDisplay]; 
     }); 
    }); 
    } 
    return cell; 
} 

任何幫助將不勝感激。提前致謝。

+2

看起來您每次都會重新下載圖像。 collectionview不會爲您緩存圖像。您需要創建自己的字典進行緩存。看看NSCache。 – yuf

+0

@yuf會做 - 謝謝! – BrianS

回答

15

@yuf - 再次感謝您的指示。 NSCache似乎讓我獲得了我以前的結果。這是正常工作的代碼。如果任何人有類似的問題,您可以將以下內容與我原來的問題進行比較。

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;{ 
    CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MY_CELL" forIndexPath:indexPath]; 

    NSString *imageName = [[self.photos objectAtIndex:indexPath.row] objectForKey:@"fullimage"]; 
    UIImage *image = [imageCache objectForKey:imageName]; 

    if(image){ 

     cell.imageView.image = image; 
    } 

    else{ 

    cell.imageView.image = nil; 

    dispatch_queue_t downloadQueue = dispatch_queue_create("image downloader", NULL); 
    dispatch_async(downloadQueue, ^{ 

     NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[[self.photos objectAtIndex:indexPath.row] objectForKey:@"fullimage"]]]; 
     UIImage *image = [UIImage imageWithData:data]; 

     dispatch_async(dispatch_get_main_queue(), ^{ 

      cell.imageView.image = image; 

     }); 

     [imageCache setObject:image forKey:imageName]; 
    }); 
    } 

    return cell; 
} 
+5

這是不完全正確的,因爲如果單元格被正確重用,則可能在圖像加載和單元更新之前,該單元的這個實例正在用於表示模型中的另一條記錄。最好更新緩存,然後調用集合視圖reloadItemsAtIndexPaths:並獲取cellForItemAtIndexPath以設置緩存中的圖像(如果它是可見的)。 – Ants

+0

啊,有道理。事實上,我遇到過這個問題(只有一次,但我明白你的意思)。謝謝! – BrianS

+0

@Ants,如果你可以添加代碼,很多人都會受益(包括我)。謝謝。 – Satyam