2010-06-07 4 views
1

저는 UITableView 셀 렌더링의 적절한 동작에 매우 혼란 스럽습니다. 상황은 다음과 같습니다.한 번에 렌더링 된 모든 UITableCell ... 이유가 무엇입니까?

나는 이미지가있는 테이블보기로로드되는 250 개의 항목 목록을 가지고 있습니다. 이미지 다운로드를 최적화하기 위해 Apple LazyTableImages 샘플 코드를 따라갔습니다. 애플의 LazyTableImages 시스템의 내 구현은 하나의 중요한 결함이있다 -

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    // customize the appearance of table view cells 
    // 
    static NSString *CellIdentifier = @"LazyTableCell"; 
    static NSString *PlaceholderCellIdentifier = @"PlaceholderCell"; 

    // add a placeholder cell while waiting on table data 
    int nodeCount = [self.entries count]; 

    if (nodeCount == 0 && indexPath.row == 0) 
    { 
     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier]; 
     if (cell == nil) 
     { 
      cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle 
              reuseIdentifier:PlaceholderCellIdentifier] autorelease]; 
      cell.detailTextLabel.textAlignment = UITextAlignmentCenter; 
      cell.selectionStyle = UITableViewCellSelectionStyleNone; 
     } 

     cell.detailTextLabel.text = @"Loading…"; 

     return cell; 
    } 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) 
    { 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle 
             reuseIdentifier:CellIdentifier] autorelease]; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 
    } 

    // Leave cells empty if there's no data yet 
    if (nodeCount > 0) 
    { 
     // Set up the cell... 
     AppRecord *appRecord = [self.entries objectAtIndex:indexPath.row]; 

     cell.textLabel.text = appRecord.appName; 
     cell.detailTextLabel.text = appRecord.artist; 

     // Only load cached images; defer new downloads until scrolling ends 
     if (!appRecord.appIcon) 
     { 
      if (self.tableView.dragging == NO && self.tableView.decelerating == NO) 
      { 
       [self startIconDownload:appRecord forIndexPath:indexPath]; 
      } 
      // if a download is deferred or in progress, return a placeholder image 
      cell.imageView.image = [UIImage imageNamed:@"Placeholder.png"];     
     } 
     else 
     { 
      cell.imageView.image = appRecord.appIcon; 
     } 

    } 

    return cell; 
} 

그래서 : 즉시 모든 이미지에 대한 모든 다운로드를 시작합니다 정말 좋은 시스템은 ... 참조를 위해, 여기에 애플의 샘플 코드 내에서 셀 렌더러입니다.

//[self startIconDownload:appRecord forIndexPath:indexPath]; 

는 그런 시스템이 당신이 예상하는 것과 같이 동작합니다 :이 줄을 제거하면 이제 그 자리는보기에 스크롤 새로운 이미지로드. 그러나 초기 뷰 셀은 셀 렌더러에서 해당 프롬프트없이 이미지를 자동으로로드하지 않습니다. 그래서, 문제가 있습니다. 셀 렌더러의 프롬프트에서 모든 이미지가 한 번에로드됩니다. 프롬프트가 없으면 초기보기가로드되지 않습니다. 자, 이것은 Apple 샘플 코드에서 잘 작동합니다.이 코드는 제게 무슨 일이 벌어지고 있는지 궁금해졌습니다. 이것은 마치 8 개가 아닌 모든 셀을 앞면에 쌓아 놓는 것과 거의 같습니다. 그래서, 나는 그것에 대해 조사하고 있는데, 이것은 사실입니다 ... 내 테이블은 250 고유 세포를 구축하고 있습니다! 난 UITableView 이런 식으로 일한 생각하지 않았다, 나는 그것이 단지 테이블을 채우는 데 필요한 많은 항목을 내장 것으로 생각 같아요. 이 경우인가요, 아니면 모든 250 셀을 앞면으로 만들겠습니까?

관련 질문 : Apple LazyTableImages 샘플과 비교하여 구현을 시도했지만 Apple 예제 코드에서 NSLog가 사용되지 않는 것으로 나타났습니다 (직접 행동 비교가 매우 어렵습니다). 그저 간단한 어딘가에 게시 설정을하거나, 애플이 어떻게 든 샘플을 잠궈서 런타임에 출력을 기록 할 수 없게 만들었습니까?

감사합니다.

답변

1

오 마이 ... mustISignUp은 "당신은 분명히 더 깊은 근본적인 문제가있다"고 말하는 것이 정확합니다. 나는 가변 높이 테이블 행을 가지고 있으며, 데이터를 채우는 데이터 모델보다는 행 자체에서 모든 높이 계산과 데이터 저장을 수행하고있었습니다. 결과적으로 모든 셀이 생성되고 셀 객체에서 셀 높이를 읽는 my heightForRowAtIndexPath 메소드로 채워집니다. 그래서 - 배운 교훈.

감사합니다. mustISignUp, 나는 당신의 사용자 이름을 사랑합니다.

+1

hehe, 기쁘게 정렬했습니다. – hooleyhoop

0

NSLog는 Apple 샘플 코드에서 확실히 비활성화되어 있지 않습니다. 왜 당신이 그것을 볼 수 없는지 모르지만 당신은 분명히 더 깊은 근본적인 문제를 가지고 있습니다.

어쨌든 비교를 위해 : 화면에 6 행이있는 경우 -tableView : cellForRowAtIndexPath :이 인덱스 [0, 0] - [0, 5]로 6 번 호출됩니다.

그래서,보고있는 게 맞습니까? -cellForRowAtIndexPath가 호출되는 횟수는 무엇입니까?

1

테이블의 모든 행에 대해 실제 UITableViewCell 인스턴스가 없어야합니다. UI에 표시되는 것보다 몇 가지 인스턴스 만 표시되어야합니다. 그것은 당신의 문제가있는 곳입니다. 그것은 이미지 로딩과 관련이 없습니다.

대기열에서 제외 된 셀이 코더가 테이블 뷰의 프레임을 변경하여 화면보다 훨씬 크게 만들었을 때 많은 수의 셀이 인스턴스화되는 것을 본 유일한 시간입니다. tableview는 표시되는 내용에 관계없이 자체 프레임에서 카펫을 제거하기에 충분한 셀을 보유합니다. 프레임이 커지면 대기열에 많은 셀이 생깁니다.

NSLog는 Apple 예제에서 작동하므로 NSLog 출력을 얻을 수 없으면 dev 도구 자체에서 이상한 일이 발생합니다.

Xcode와 시뮬레이터를 종료하고 다시 시작하여 비정상적인 동작을 제거 할 수 있습니다.

관련 문제