2012-12-13 24 views
7

私はObjective-Cをかなり新しくしています。うまくいけば、これはすべて意味があります。私はサーバーから画像をダウンロードし、collectionView cellForItemAtIndexPath:メソッドの画像ビューで表示しました。私が直面している問題は、画像がキャッシュされていないように見えることです。セルが再利用されるたびに、サーバからの関連イメージが再ダウンロードされているように見えます。イメージとUICollectionViewのキャッシュ

私はNSMutableDictionaryを作成しています私のviewDidLoadメソッドで

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

関連する問題