2012-12-13 2 views
7

저는 Objective-C에 익숙하기 때문에이 모든 것이 의미가 있습니다. 서버에서 이미지를 다운로드 한 후 collectionView cellForItemAtIndexPath: 방법으로 이미지보기에 표시했습니다. 내가 직면 한 문제는 이미지가 캐싱되지 않는 것입니다. 셀을 다시 사용할 때마다 서버의 관련 이미지가 다시 다운로드되는 것처럼 보입니다. 설명서를 읽고 난 그이 생각 유사한 질문에 대한 답변보고에서이미지 및 UICollectionView 캐싱

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

을 더한 다음 코드는 충분하다 : 내있는 viewDidLoad 방법에

은 내가 NSMutableDictionary를 만드는거야. 나는 며칠 동안이 일을 해왔으며, 내가 누락 된 것 또는 내가 이해하지 못하는 개념이 있음을 안다.

#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