찾다

 >  Q&A  >  본문

ios - 关于cell重用的一些很纠结的问题(来大神解释下)


static NSString *orderCellID = @"MyOrderCell";

[self.mTableView registerClass:[MyOrderCell class] forCellReuseIdentifier:orderCellID];
1.MyOrderCell *cell = (MyOrderCell *)[tableView dequeueReusableCellWithIdentifier:orderCellID];

    if (cell == nil) {

       cell = [[MyOrderCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:orderCellID];

    }
2.MyOrderCell *cell = [self.mTableView dequeueReusableCellWithIdentifier:orderCellID forIndexPath:indexPath];

这两种重用cell的方法问题就是...

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
    
    NSLog(@"cell height %f",cell.frame.size.height);
    
    return cell.frame.size.height;
}

如果用方法2.的话为什么
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
就报错了?????

但是用方法1的话确实是可行的...可以来个大神详细解释下吗

大家讲道理大家讲道理2771일 전607

모든 응답(5)나는 대답할 것이다

  • 怪我咯

    怪我咯2017-04-17 16:56:14

    두 가지 방법은 실제로 동일합니다. 즉,

    [self.mTableView dequeueReusableCellWithIdentifier:orderCellID forIndexPath:indexPath];

    이 메서드는 재사용 대기 중인 생성된 셀이 있는지 여부에 관계없이 셀 반환이 보장됩니다(있는 경우 해당 셀을 가져오고, 없으면 새 셀이 생성됩니다). 하지만 이 메소드를 호출할 때 조건이 있는데, 즉 본 문서에 적힌 대로 등록을 위해서는 반드시 RegisterClass나 RegisterNib 메소드를 호출해야 한다는 것입니다.
    또 다른 방법은 재사용 대기 중인 생성 셀이 있는지 확인하는 것입니다. 셀이 있으면 하나 가져와 반환하고, 없으면 nil을 반환하므로 아래에서 nil인지 확인하여 생성해야 합니다. 당신 자신.

    [self tableView:tableView cellForRowAtIndexPath:indexPath];

    이 메서드는 수동으로 호출할 수 없습니다. 이 메서드에서 반환된 셀은 인터페이스에 표시되고 재사용에 참여합니다. 이 메서드를 수동으로 호출하면 반환된 셀은 쓸모가 없으며 높이를 계산한 후에 해제됩니다. . 코드의 계산량이 높으면 메서드가 호출될 때마다 셀이 생성됩니다.

    따라서 여러분이 겪고 있는 재사용 문제는 실제로 tableView:cellForRowAtIndexPath: 함수를 수동으로 호출했기 때문에 발생합니다.

    회신하다
    0
  • ringa_lee

    ringa_lee2017-04-17 16:56:14

    1 가능하더라도 반환값은 nil이어야 합니다

    회신하다
    0
  • 天蓬老师

    天蓬老师2017-04-17 16:56:14

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    
        UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
        
        NSLog(@"셀 높이 %f",cell.frame.size.height);
        
        cell.frame.size.height를 반환합니다.
    }

    이 코드는 일반적으로 이렇게 작성할 수 없습니다. 높이를 반환하려면 이와 같이 셀을 가져온 다음 높이를 반환할 수 없습니다. 이 프록시 메소드가 호출될 때 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath가 아직 실행되지 않았다는 것을 알아야 합니다. 두 가지의 호출 순서는 필수입니다. 이해되다.
    Tableview에서는 미리 높이를 얻어와야 하며, 그 셀을 재사용하여 셀을 반환합니다. 셀은 이전 높이에 따라 배치됩니다.

    따라서 높이를 반환하는 프록시 메서드에는 일반적으로 두 가지 아이디어가 있습니다.

    <올>
  • 셀 내부의 다양한 UI 요소의 높이와 간격을 가져와서 누적 계산을 수행합니다. 아래 참조 링크를 참조하세요.

  • 자동 레이아웃 제약 조건을 사용하는 경우 `[cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]를 사용하여 높이를 계산합니다. 이에 대해서는
    오픈 소스 프로젝트 https://github.com/을 참조하세요. forkingdog/UITableView-FDTemplateLayoutCell< /p>

  • 다음을 살펴볼 수 있습니다: UITableViewCell 높이의 동적 계산에 대한 자세한 설명

    회신하다
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-17 16:56:14

    위 사람 말이 맞아요. 시스템의 프록시 메서드를 직접 호출하지 않는 것이 가장 좋습니다. 그렇지 않으면 완전히 보장되지 않으면 문제가 발생할 수 있습니다.
    그리고 포스터의 질문은 2입니다. MyOrderCell *cell = [self.mTableView dequeueReusableCellWithIdentifier:orderCellID forIndexPath:indexPath]; 왜 이렇게 되지 않나요?

    공식 문서에서는 dequeueReusableCellWithIdentifier에 대해 설명합니다::
    식별자로 위치한 재사용 가능한 테이블 뷰 셀 개체를 반환합니다.
    재사용할 셀 개체를 식별하는 문자열입니다. 전무.

    연관된 식별자가 있는 UITableViewCell 개체를 반환합니다. 또는 해당 개체가 재사용 가능 셀 큐에 없으면 nil.

    재사용 가능한 셀을 갖고 싶다면 먼저 셀을 만들어야 한다는 사실을 보셨나요? 아직 생성하지 않은 경우 시스템에서 생성되지 않습니다. 첫 번째 방법은 올바른 것입니다. 시스템이 재사용 가능한 셀이 없다는 것을 발견하면 nil을 반환하고 사용자가 직접 셀을 할당하기 때문입니다. 다음번에는 이 셀이 대기열에 추가됩니다. 재사용할 때 시스템에서
    참고용으로 찾았습니다: 링크 설명

    회신하다
    0
  • 大家讲道理

    大家讲道理2017-04-17 16:56:14

    두 번째 방법은 먼저 tableView에 셀을 등록하는 것입니다

    회신하다
    0
  • 취소회신하다