dequeueReusableCellWithIdentifier : forIndexPath에서 어설 션 실패 :


324

그래서 저는 학교에서 RSS 리더를 만들고 코드를 완성했습니다. 테스트를 실행했는데 오류가 발생했습니다. 참조하는 코드는 다음과 같습니다.

- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = 
     [tableView dequeueReusableCellWithIdentifier:CellIdentifier 
                                     forIndexPath:indexPath];
    if (cell == nil) {

        cell = 
         [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle  
                                reuseIdentifier:CellIdentifier];

    }

출력의 오류는 다음과 같습니다.

2012-10-04 20 : 13 : 05.356 Reader [4390 : c07] *-[UITableView dequeueReusableCellWithIdentifier : forIndexPath :], /SourceCache/UIKit_Sim/UIKit-2372/UITableView.m:4460의 어설 션 실패 13 : 05.357 Reader [4390 : c07] * 포착되지 않은 예외 'NSInternalInconsistencyException'으로 인해 앱을 종료하는 이유 : '식별자 셀이있는 셀을 큐에서 빼낼 수 없음-식별자에 대한 펜촉 또는 클래스를 등록하거나 스토리 보드에서 프로토 타입 셀을 연결해야합니다. ' * 먼저 던져 호출 스택 : (0x1c91012 0x10cee7e 0x1c90e78 0xb64f35 0xc7d14 0x39ff 0xd0f4b 0xd101f 0xb980b 0xca19b 0x6692d 0x10e26b0 0x228dfc0 0x228233c 0x228deaf 0x1058cd 0x4e1a6 0x4ccbf 0x4cbd9 0x4be34 0x4bc6e 0x4ca29 0x4f922 0xf9fec 0x46bc4 0x47311 0x2cf3 0x137b7 0x13da7 0x14fab 0x26315 0x2724b 0x18cf8 0x1becdf9 0x1becad0 0x1c06bf5 0x1c06962 0x1c37bb6 0x1c36f44 0x1c36e1b 0x147da 0x1665c 0x2a02 0x2935 ) libc ++ abi.dylib : 예외가 발생하여 종료 호출

오류 화면에 표시되는 코드는 다음과 같습니다.

int main(int argc, char *argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

도와주세요!


답변:


488

dequeueReusableCellWithIdentifier:forIndexPath:방법을 사용하고 있습니다. 문서 그 방법이 말한다 :

중요 사항 : 이 메소드를 호출하기 전에 registerNib:forCellReuseIdentifier:or registerClass:forCellReuseIdentifier:메소드를 사용하여 클래스 또는 nib 파일을 등록해야합니다 .

재사용 식별자에 펜촉 또는 클래스를 등록하지 않았습니다 "Cell".

코드를 보면 dequeue 메소드가 nil셀을 제공하지 않으면 리턴 메소드가 리턴 될 것으로 예상 됩니다. dequeueReusableCellWithIdentifier:해당 동작을 위해 를 사용해야합니다 .

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

공지 사항 것을 dequeueReusableCellWithIdentifier:dequeueReusableCellWithIdentifier:forIndexPath:다른 방법이 있습니다. 전자후자 doc을 참조하십시오 .

당신은 당신이 이제까지 사용 싶어 이유를 이해하려면 dequeueReusableCellWithIdentifier:forIndexPath:, 이 Q & A를 확인 .


166
세상에 UITableViewController에 대한 Xcode의 기본 템플릿이 dequeueReusableCellWithIdentifier : forIndexPath :를 자동으로 제공하는 이유는 무엇입니까? 너무 도움이되지 않습니다.
spstanley

15
dequeueReusableCellWithIdentifer:forIndexPath:당신이 셀이 전무가 있는지 확인 할 필요가 없기 때문에 (iOS6의 도입), 멋진 개선이다. (그래서 UITableViewController비슷하게 작동합니다 UICollectionView) 그러나 예,이 변경 사항이 템플릿에 주석이 없으며 어설 션 / 충돌 메시지가 더 도움이되지 않는다는 성가심.
Jason Moore

2
최소한 내재화 대신 UITableViewCell을 기본값으로 사용한다고 생각할 것입니다. 바카
BadPirate

13
이 답변의 마지막 줄은 황금색입니다.을 dequeueReusableCellWithIdentifier:forIndexPath:사용해야 할 때 사용하여 두 번 이상 물 렸습니다 dequeueReusableCellWithIdentifier:.
ele

이 답변은 완벽합니다. 질문이 있습니다 : 초기 뷰 컨트롤러로 tableViewController가 있습니다. didSelectRow에서 ... 다른 tableViewController를 탐색 스택에 푸시하고 있습니다. 어떻게 초기가 아닌 두 번째 tableViewController에 셀을 등록해야합니까?
ArielSD

137

이 오류는 식별자에 펜촉 또는 클래스를 등록하는 것과 관련이 있다고 생각합니다.

tableView : cellForRowAtIndexPath 함수에서 수행중인 작업을 유지하고 viewDidLoad에 아래 코드를 추가하십시오.

[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];

그것은 나를 위해 일했다. 그것이 도움이되기를 바랍니다.


3
이것에 대한 하나의 작은 문제-재사용 식별자가 해당 셀의 스토리 보드 설정에서 설정 한 것과 일치하는지 확인하십시오.
James Boutcher

약간 다른 유스 케이스에 이것을 추가하기 위해 SplitViewController의 마스터보기에서 행을 다시 선택했습니다. 이 행 선택 다시 논리에 있었고이 viewDidLoad논리를 이동하여 viewDidAppear수정했습니다.
Craig Conover

cell == nil에 들어갈 수 없으므로 tableview 셀은 항상 nil입니다.
솔리드 소프트

3
스위프트 3.0 : self.tableView.register (UITableViewCell.classForCoder (), forCellReuseIdentifier : "Cell");
norbDEV

68

이 질문은 상당히 오래되었지만 다른 가능성이 있습니다. 스토리 보드를 사용하는 경우 스토리 보드에서 CellIdentifier를 설정하기 만하면됩니다.

CellIdentifier가 "Cell"인 경우 "Identifier"특성을 설정하십시오. 여기에 이미지 설명을 입력하십시오

그렇게 한 후에 빌드를 청소하십시오. XCode는 때때로 스토리 보드 업데이트에 문제가 있습니다


3
당신은 굉장합니다, 청소는 많이합니다! : D
Sandy

2
참고- "Cell"이외의 식별자를 사용하는 경우 다음 줄에서이 식별자를 사용하도록 cellForRowAtIndexPath 메소드도 변경해야합니다. static NSString * CellIdentifier = @ "MyCellIdentifier";
gamozzii

5
이에 대한 한 가지 중요한 추가 사항 : 테이블 뷰에는 "정적 셀"이 아니라 "콘텐츠"속성이 "동적 프로토 타입"으로 설정되어 있어야합니다.
Ted Avery

이 답변은 더 높아져야합니다. 매우 유용
Sukitha Udugamasooriya

Identifier속성 을 업데이트 한 후 청소 빌드가 필수적이었습니다 . 감사!
Crashalot

59

나는 같은 문제로 교체했다

static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

   if (cell==nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];

    }

해결


감사합니다. 이것은 방금 두통을 구했습니다. =)
Robert

3
:-(id) dequeueReusableCellWithIdentifier : forIndexPath : 를 사용하면 셀이 nil인지 확인할 필요가 없습니다. (IOS6>)
seufagner

방금 두통을 저축했습니다. =)
Abo3atef

26

UITableViewCell스토리 보드에서 사용자 정의를 구성 하지만 스토리 보드를 사용하여 UITableViewController이것을 사용 하는 인스턴스를 인스턴스화하지 않기 때문에 문제가 발생했을 가능성이 큽니다 UITableViewCell. 예를 들어, MainStoryboard에, 당신은이 UITableViewController라는 서브 클래스 MyTableViewController및 사용자 정의 동적있다 UITableViewCell라는 MyTableViewCell식별자 ID가 "MyCell"로한다.

다음 UITableViewController과 같이 사용자 정의를 작성하는 경우 :

 MyTableViewController *myTableViewController = [[MyTableViewController alloc] init];

사용자 정의 테이블 뷰셀을 자동으로 등록하지 않습니다. 수동으로 등록해야합니다.

그러나 스토리 보드를 사용하여 인스턴스화하는 경우 다음 MyTableViewController과 같이하십시오.

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
MyTableViewController *myTableViewController = [storyboard  instantiateViewControllerWithIdentifier:@"MyTableViewController"];

좋은 일이 일어난다! UITableViewController스토리 보드에서 정의한 사용자 정의 테이블 뷰 셀을 자동으로 등록합니다.

델리게이트 메소드 "cellForRowAtIndexPath"에서 다음과 같이 테이블 뷰 셀을 작성할 수 있습니다.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"MyCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

//Configure your cell here ...

return cell;
}

재활용 대기열에 재사용 가능한 셀이 없으면 dequeueReusableCellWithIdentifier가 자동으로 새 셀을 만듭니다.

그런 다음 끝났습니다!


instantiateViewControllerWithIdentifier내 viewController를 초기화 하는 데 사용 하는 팁이 내 하루를 구했습니다!
Lei Zhang

내 하루를 구했습니다 : 프로토 타입 셀이 테이블과 함께 인접한 VC에있었습니다
Anton Tropashko

이것이 제 경우에는 합리적인 원인입니다.
노라 Alnashwan

19

Xcode 4.5 에는 dequeueReusableCellWithIdentifier:forIndexPath:
기본 템플릿 코드에 새로운 기능이 포함되어 있다고 덧붙일 것 입니다. 개발자는 이전 dequeueReusableCellWithIdentifier:방법을 기대할 수 있습니다.


저를 ung! 이제 더 잘 알겠습니다. ;)
spstanley

18

스토리 보드에서 프로토 타입 셀의 '식별자'를 CellReuseIdentifier "셀"과 동일하게 설정해야합니다. 그런 다음 해당 메시지를 얻지 못하거나 해당 registerClass : 함수를 호출해야합니다.


2
잡았다! '100 upvotes'버튼은 어디에 있습니까? 이것이 실제 솔루션입니다.
Jojo.Lechelt

스토리 보드에 새 tableView를 추가하면 기본 식별자 인 'Cell'이 제공됩니다. tableView : cellForRowAtIndexPath에서 소위 '무료 코드'를 사용하는 경우 특히 간과됩니다.
ushika

18

스위프트 2.0 솔루션 :

Attribute Inspector로 이동하여 셀 식별자 이름을 추가해야합니다.

여기에 이미지 설명을 입력하십시오

그런 다음 식별자를 다음과 같이 대기열과 일치시켜야합니다.

let cell2 = tableView.dequeueReusableCellWithIdentifier("ButtonCell", forIndexPath: indexPath) as! ButtonCell

대안 적으로

펜촉으로 작업하는 경우 cellForRowAtIndexPath에 클래스를 등록해야 할 수도 있습니다.

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {       

    tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "SwitchCell")

    // included for context            
    let cell = tableView.dequeueReusableCellWithIdentifier("SwitchCell", forIndexPath:indexPath) as! SwitchCell

    //... continue    
}

애플의 UITableView 클래스 레퍼런스는 다음과 같이 말합니다.

셀을 큐에서 빼기 전에이 메소드 또는 registerNib : forCellReuseIdentifier : 메소드를 호출하여 테이블보기에 새 셀 작성 방법을 알려주십시오. 지정된 유형의 셀이 현재 재사용 큐에없는 경우 테이블보기는 제공된 정보를 사용하여 새 셀 오브젝트를 자동으로 작성합니다.

동일한 재사용 식별자로 클래스 또는 nib 파일을 이전에 등록한 경우 cellClass 매개 변수에 지정한 클래스가 이전 항목을 대체합니다. 지정된 재사용 식별자에서 클래스를 등록 취소하려는 경우 cellClass에 nil을 지정할 수 있습니다.

Apples Swift 2.0 프레임 워크의 코드는 다음과 같습니다.

// Beginning in iOS 6, clients can register a nib or class for each cell.
// If all reuse identifiers are registered, use the newer -dequeueReusableCellWithIdentifier:forIndexPath: to guarantee that a cell instance is returned.
// Instances returned from the new dequeue method will also be properly sized when they are returned.

@available(iOS 5.0, *)
func registerNib(nib: UINib?, forCellReuseIdentifier identifier: String)

@available(iOS 6.0, *)
func registerClass(cellClass: AnyClass?, forCellReuseIdentifier identifier: String)

나는 어디에서 오는지 이해하지 못 SwitchCell.self합니까?
Gert Cuykens

@GertCuykens SwitchCell은 내 사용자 정의 UITableViewCell입니다
Dan Beaulieu

1
지금은 Mac을 사용하지 않지만 집에 도착했을 때 확실히 업데이트 할 수 있습니다.
Dan Beaulieu

1
그것을 대체하면 UITableViewCell.self나에게 효과가 있는 것 같습니다. 답에 메모를 추가 할 수도 있습니다.
Gert Cuykens

그 밖의 포인팅에 대한 감사를 @GertCuykens, 나는 UITableViewCell.self에 대한 SwitchCell.self을 변경 한
댄 보리

3

당신이가는 경우 사용자 정의 정적 세포 만이 방법을 언급 :

//- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//    static NSString *CellIdentifier = @"notificationCell";
//    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
//    return cell;
//}

스토리 보드의 "속성 관리자" 에서 셀에 식별자를 제공합니다 .


3

Objective C와 Swift 둘 다에 대한 답변을 드리겠습니다.

를 사용하는 경우 Apple Documnetation Says에 따라이dequeueReusableCellWithIdentifier:forIndexPath: 메소드를 호출하기 전에 registerNib : forCellReuseIdentifier : 또는 registerClass : forCellReuseIdentifier : 메소드를 사용하여 클래스 또는 펜촉 파일을 등록해야합니다.

그래서 우리는 추가 registerNib:forCellReuseIdentifier: or registerClass:forCellReuseIdentifier:

지정된 식별자에 대한 클래스를 등록하고 새 셀을 작성해야하는 경우이 메소드는 initWithStyle : reuseIdentifier : 메소드를 호출하여 셀을 초기화합니다. 펜촉 기반 셀의 경우이 방법은 제공된 펜촉 파일에서 셀 객체를로드합니다. 기존 셀을 재사용 할 수있는 경우이 메소드는 대신 셀의 prepareForReuse 메소드를 호출합니다.

viewDidLoad 메소드에서 우리는 셀을 등록해야합니다

목표 C

옵션 1:

[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"];

옵션 2 :

[self.tableView registerNib:[UINib nibWithNibName:@"CustomCell" bundle:nil] forCellReuseIdentifier:@"cell"];

위의 코드에서 nibWithNibName:@"CustomCell" 에서 내 펜촉 이름 CustomCell 대신 펜촉 이름을 지정하십시오.

빠른

옵션 1:

tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")

옵션 2 :

tableView.registerNib(UINib(nibName: "NameInput", bundle: nil), forCellReuseIdentifier: "Cell") 

위의 코드에서 nibName:"NameInput"펜촉 이름을 지정하십시오.


3

Swift 3.0으로 작업하기 :

override func viewDidLoad() {
super.viewDidLoad()

self.myList.register(UINib(nibName: "MyTableViewCell", bundle: nil), forCellReuseIdentifier: "Cell")
}



public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = myList.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath) as! MyTableViewCell

return cell
}

2

지난 밤에 프로그래밍 방식으로 생성 된 테이블이 [myTable setDataSource : self]에서 충돌 한 이유를 해결하기 위해 몇 시간을 보냈습니다. 주석을 달아서 빈 테이블을 팝업했지만 데이터 소스에 도달하려고 할 때마다 충돌했습니다.

나는 h 파일에 위임을 설정했습니다 : @interface myViewController : UIViewController

구현에 데이터 소스 코드가 있었지만 여전히 BOOM!이 충돌합니다! "xxd"감사합니다 (번호 9) : 해당 코드 줄을 추가하면 문제가 해결되었습니다. 실제로 IBAction 버튼에서 테이블을 시작하므로 전체 코드는 다음과 같습니다.

    - (IBAction)tapButton:(id)sender {

    UIViewController* popoverContent = [[UIViewController alloc]init];

    UIView* popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 300)];
    popoverView.backgroundColor = [UIColor greenColor];
    popoverContent.view = popoverView;

    //Add the table
    UITableView *table = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 200, 300)         style:UITableViewStylePlain];

   // NEXT THE LINE THAT SAVED MY SANITY Without it the program built OK, but crashed when      tapping the button!

    [table registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];
    table.delegate=self;
    [table setDataSource:self];
    [popoverView addSubview:table];
    popoverContent.contentSizeForViewInPopover =
    CGSizeMake(200, 300);

    //create a popover controller
    popoverController3 = [[UIPopoverController alloc]
                          initWithContentViewController:popoverContent];
    CGRect popRect = CGRectMake(self.tapButton.frame.origin.x,
                                self.tapButton.frame.origin.y,
                                self.tapButton.frame.size.width,
                                self.tapButton.frame.size.height);


    [popoverController3 presentPopoverFromRect:popRect inView:self.view   permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];



   }


   #Table view data source in same m file

   - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
   {
    NSLog(@"Sections in table");
    // Return the number of sections.
    return 1;
   }

   - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
  {
    NSLog(@"Rows in table");

    // Return the number of rows in the section.
    return myArray.count;
   }

   - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath    *)indexPath
    {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    NSString *myValue;

    //This is just some test array I created:
    myValue=[myArray objectAtIndex:indexPath.row];

    cell.textLabel.text=myValue;
    UIFont *myFont = [ UIFont fontWithName: @"Arial" size: 12.0 ];
    cell.textLabel.font  = myFont;

    return cell;
   }

그건 그렇고 : 팝 오버를 고정하려면 버튼을 IBAction 및 IBOutlet으로 연결해야합니다.

UIPopoverController * popoverController3는 {} 사이의 @interface 바로 다음에 H 파일에 선언됩니다.


2

FWIW, 스토리 보드에서 셀 식별자를 설정하는 것을 잊었을 때 이와 동일한 오류가 발생했습니다. 이것이 문제인 경우 스토리 보드에서 테이블 뷰 셀을 클릭하고 속성 편집기에서 셀 식별자를 설정하십시오. 여기에서 설정 한 셀 식별자가

static NSString *CellIdentifier = @"YourCellIdenifier";

2

나는 같은 문제가 있었고 같은 오류가 있었고 나를 위해 다음과 같이 일했다.

[self.tableView registerNib:[UINib nibWithNibName:CELL_NIB_HERE bundle: nil] forCellReuseIdentifier:CELL_IDENTIFIER_HERE];

다른 사람에게 유용 할 수 있습니다.


2

I 설치 스토리 보드에서 제대로 모든 및 정리 빌드를했지만 "오류를 얻고 유지 식별자에 대한 펜촉 또는 클래스를 등록 또는 스토리 보드에서 프로토 타입 셀을 연결해야합니다 "

[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];

오류를 수정했지만 여전히 손실이 있습니다. 나는 '사용자 정의 셀'을 사용하지 않고 테이블 뷰가 포함 된보기 만 사용합니다. 뷰 컨트롤러를 델리게이트 및 데이터 소스로 선언했으며 셀 식별자가 파일에서 일치하는지 확인했습니다. 무슨 일이야?


1

이것은 일부 사람들에게는 어리석은 것처럼 보이지만 저를 얻었습니다. 나는이 오류를 겪고 있었고 문제는 정적 셀을 사용하려고했지만 동적으로 더 많은 것을 추가한다는 것입니다. 이 메소드를 호출하는 경우 셀은 동적 프로토 타입이어야합니다. 스토리 보드와 속성 관리자에서 셀을 선택하면 가장 먼저 '콘텐츠'라고 표시되며 정적이 아닌 동적 프로토 타입을 선택해야합니다.


감사합니다! 이것은 정확히 내 문제였습니다.
이사야 터너

1

그냥 답변을 보충 : 당신이 바로 모든 것을 설정 시간을있을 수 있습니다,하지만 당신은 실수에 다른 UI를 추가 할 수 .xib는 A, UIButton: 여기에 이미지 설명을 입력하십시오 그냥 별도의 UI를 삭제하고, 그것을 작동합니다.


1

스토리 보드에서 셀의 CellIdentifier == 셀 식별자이며 두 이름이 모두 같은지 확인하십시오. 희망이 당신을 위해 작동


0

내 경우에는 전화했을 때 충돌이 발생했습니다.deselectRowAtIndexPath:

라인은 [tableView deselectRowAtIndexPath:indexPath animated:YES];

문제 수정으로 변경 [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; !

이것이 누군가를 돕기를 바랍니다.


0

Swift 에서이 문제는 다음 코드를 추가하여 해결할 수 있습니다

viewDidLoad

방법.

tableView.registerClass(UITableViewCell.classForKeyedArchiver(), forCellReuseIdentifier: "your_reuse_identifier")

-1

이 오류가 발생했습니다. bc 셀 재사용 식별자가 잘못되었습니다. 신인 실수이지만 다음과 같은 일이 발생합니다. 2. 같은 줄을 따라 대문자 사용 횟수를 잊지 마십시오. 3. 0은 "O"가 아닙니다 (Ohs).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.