2011-10-21 4 views
8

사용자 정의 셀이있는 UITableView가 있습니다. Grand Central Dispatch를 사용하여 이미지를 비동기 적으로로드합니다. 모든 것이 잘 작동하지만 아래로 스크롤하면 이전에로드 된 이미지가 새 이미지가 다운로드 될 때까지 표시됩니다.GCD UITableView 비동기로드 이미지, 새 이미지 다운로드까지 잘못된 셀로드 됨

if (![[NSFileManager defaultManager] fileExistsAtPath:[path stringByAppendingPathComponent:@"image.png"]]) 
{ 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
    dispatch_async(queue, ^{ 
     NSString *url=[pat stringByAppendingPathComponent:@"comments.txt"]; 
     NSString *u=[NSString stringWithContentsOfFile:url encoding:NSUTF8StringEncoding error:nil]; 
     NSURL *imageURL=[NSURL URLWithString:u]; 
     NSData *image=[NSData dataWithContentsOfURL:imageURL]; 
     [image writeToFile:[pat stringByAppendingPathComponent:@"image.png"] atomically:YES]; 
     dispatch_sync(dispatch_get_main_queue(), ^{ 
      cell.imageView.image=[UIImage imageWithContentsOfFile:[pat stringByAppendingPathComponent:@"image.png"]]; 
      [cell setNeedsLayout]; 
      NSLog(@"Download"); 
     }); 
    }); 
} 
else 
{ 
    NSLog(@"cache"); 
    cell.imageView.image=[UIImage imageWithContentsOfFile:[pat stringByAppendingPathComponent:@"image.png"]]; 
} 

어떤 제안 평가 : 여기 내 코드입니다. 오후 8시 30 분 P.S. 셀을 다시 사용합니다.

답변

18

오히려 인덱스 경로를 캡처하는 데 필요한 세포를 캡처하는 것보다, 다음 사용하여 다시 세포를 얻을 :

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 

그 방법을, 셀이 다시 전무를 얻을 수 있습니다 화면과 이미지 꺼지면 잘못된 셀에 설정되지 않습니다.

dispatch_async() 뒤에 추가해야 할 다른 사항은 cell.imageView.image=somePlaceholderImage입니다.

예컨대 :

if (![[NSFileManager defaultManager] fileExistsAtPath:[path stringByAppendingPathComponent:@"image.png"]]) 
{ 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
    dispatch_async(queue, ^{ 
     NSString *url=[pat stringByAppendingPathComponent:@"comments.txt"]; 
     NSString *u=[NSString stringWithContentsOfFile:url encoding:NSUTF8StringEncoding error:nil]; 
     NSURL *imageURL=[NSURL URLWithString:u]; 
     NSData *image=[NSData dataWithContentsOfURL:imageURL]; 
     [image writeToFile:[pat stringByAppendingPathComponent:@"image.png"] atomically:YES]; 
     dispatch_sync(dispatch_get_main_queue(), ^{ 
      UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
      cell.imageView.image=[UIImage imageWithContentsOfFile:[pat stringByAppendingPathComponent:@"image.png"]]; 
      [cell setNeedsLayout]; 
      NSLog(@"Download"); 
     }); 
    }); 
    cell.imageView.image=[UIImage imageNamed:@"placeholder"]; 
} 
else 
{ 
    NSLog(@"cache"); 
    cell.imageView.image=[UIImage imageWithContentsOfFile:[pat stringByAppendingPathComponent:@"image.png"]]; 
} 
+0

답장을 보내 주셔서 감사합니다.하지만 몇 가지 예제 코드를 제공해 주시겠습니까? – blackhawk4152

+0

내 대답이 업데이트되었습니다 – hypercrypt

+0

감사합니다. 그냥 내가 원했던 것 – blackhawk4152

2

- (void)tableView:(UITableView *)aTableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { 이미지를 지우거나 회 전자로 재설정해야합니다. 테이블 뷰 행이 재사용되므로 이는 사용자에게 표시되는 동작입니다.

2

정의있는 UITableViewCell하지 않습니다 - 그 목적을 위해 (무효) prepareForReuse를? 오버라이드하고 이미지 뷰를 지 웁니다.

+0

[documentation] (http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableViewCell_Class/Reference/Reference.html#//apple_ref/occ/instm/UITableViewCell/prepareForReuse) 당신은 prepareForReuse 안에있는 내용을 만지지 않아야합니다. 대신 cellForRowAtIndexPath의 내용을 재설정해야합니다. –

관련 문제