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のアサーションエラー2012-10-04 20: 13:05.357 Reader [4390:c07] *キャッチされない例外 'NSInternalInconsistencyException'によりアプリを終了しています、理由: '識別子Cellでセルをデキューできません-識別子のnibまたはクラスを登録するか、ストーリーボードのプロトタイプセルを接続する必要があります' *まずスローコールスタック(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 ++ abidyと呼ばれるlibc ++ abidy

エラー画面に表示されるコードは次のとおりです。

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"

あなたのコードを見ると、あなたnilが与えるセルを持っていない場合、dequeueメソッドが返ると期待しているようです。dequeueReusableCellWithIdentifier:その動作にはを使用する必要があります。

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

dequeueReusableCellWithIdentifier:dequeueReusableCellWithIdentifier:forIndexPath:は異なる方法であることに注意してください。前者後者については、ドキュメントを参照してください。

なぜ使用したいのかを理解したい場合はdequeueReusableCellWithIdentifier:forIndexPath:このQ&Aを確認してください


166
ああ、神様。XcodeのUITableViewControllerのデフォルトテンプレートでdequeueReusableCellWithIdentifier:forIndexPath:が自動的に提供されるのはなぜですか?とても役に立たない。
spstanley

15
dequeueReusableCellWithIdentifer:forIndexPath:あなたはセルがnilであるかどうかを確認する必要がないので、(iOS6で導入)は、素敵な改良です。(これUITableViewControllerはと同様に機能しますUICollectionView)しかし、そうです、この変更がテンプレート内のコメントではなく、アサーション/クラッシュメッセージはそれほど役に立ちません。
Jason Moore

2
少なくとも、デフォルトでは、内破するのではなくUITableViewCellになると思います。バカ。
BadPirate 2013年

13
この回答の最後の行はゴールデンです。私はを使用dequeueReusableCellWithIdentifier:forIndexPath:するべきだったときに使用することで、何度も噛まれましたdequeueReusableCellWithIdentifier:
ele 2013

この答えは完璧です。質問があります。最初のビューコントローラとしてtableViewControllerがあります。didSelectRowで...別のtableViewControllerをナビゲーションスタックにプッシュしています。最初のセルではなく、2番目のtableViewControllerのセルを登録する必要があるのはなぜですか?
ArielSD 2017

137

このエラーは、ニブまたはクラスを識別子に登録することに関するものだと思います。

そのため、tableView:cellForRowAtIndexPath関数で行っていることを維持し、以下のコードをviewDidLoadに追加するだけです。

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

それは私のために働いた。お役に立てれば幸いです。


3
これに関する1つの小さな問題-再利用識別子が、問題のセルのストーリーボード設定で設定したものと一致することを確認してください。
James Boutcher 2013年

少し異なるユースケースでこれに追加するために、SplitViewControllerのマスタービューで行を再選択していました。この行再選択ロジックはにありviewDidLoad、このロジックをviewDidAppear修正して修正しました。
Craig Conover、2014

cell == nilに入力できなかったため、テーブルビューのセルは常にnilです。
2014

3
swift 3.0:self.tableView.register(UITableViewCell.classForCoder()、forCellReuseIdentifier: "Cell");
norbDEV 2016

68

この質問はかなり古いですが、別の可能性があります。ストーリーボードを使用している場合は、ストーリーボードでCellIdentifierを設定するだけです。

したがって、CellIdentifierが「Cell」の場合は、「Identifier」プロパティを設定するだけです。 ここに画像の説明を入力してください

そうした後は必ずビルドをクリーンアップしてください。XCodeにストーリーボードの更新に関する問題が時々ある


3
あなたは素晴らしいです、掃除はたくさんします!! :D
Sandy

2
注-「Cell」以外の識別子を使用する場合は、次の行でこの識別子を使用するようにcellForRowAtIndexPathメソッドを変更する必要もあります。static NSString * CellIdentifier = @ "MyCellIdentifier";
gamozzii 2013年

5
これに対する1つの重要な追加:テーブルビューの「コンテンツ」属性は、「静的セル」ではなく「動的プロトタイプ」に設定する必要があります
Ted Avery

この答えは高くなる必要があります。非常に役立つ
Sukitha Udugamasooriya 14

Identifierプロパティを更新した後、ビルドのクリーニングが不可欠でした。ありがとう!
Crashalot、2015

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 2013

頭痛を和らげてくれました。=)
Abo3atef 2014年

26

この問題はUITableViewCell、ストーリーボードでカスタムを設定しているが、ストーリーボードUITableViewControllerを使用して、これを使用するをインスタンス化していないことが原因と考えられますUITableViewCell。たとえば、MainStoryboardでは、UITableViewControllerサブクラスが呼び出されMyTableViewController、カスタムダイナミックが識別子ID「MyCell」でUITableViewCell呼び出さMyTableViewCellれます。

次の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を初期化することで私の1日が節約できました。
Lei Zhang

私の日を救った:プロトタイプセルがテーブルのある隣接するVCにあった
Anton Tropashko 2016年

これが私の場合の合理的な原因です。
Nora Alnashwan、2016年

19

Xcode 4.5には、dequeueReusableCellWithIdentifier:forIndexPath:
デフォルトのテンプレートコードに新しいものが含まれていることを追加しますdequeueReusableCellWithIdentifier:。これは、古い方法を期待する開発者にとって潜在的な問題です。


私を刺した!今、私はよく知っているでしょう。;)
spstanley

18

ストーリーボードで、プロトタイプセルの「識別子」をCellReuseIdentifier "Cell"と同じになるように設定する必要があります。次に、そのメッセージを取得しないか、そのregisterClass:関数を呼び出す必要があります。


2
ゲッチャ!「100票」ボタンはどこにありますか。これが本当の解決策です。
Jojo.Lechelt 2013年

新しいtableViewをストーリーボードに追加すると、デフォルトの識別子「Cell」が提供されると考えられます。特にtableView:cellForRowAtIndexPathでいわゆる「無料コード」を使用している場合は、見落とされがちです。
ushika 2013年

18

Swift 2.0ソリューション:

属性インスペクターに移動し、セルの名前を追加する必要があります識別子:

ここに画像の説明を入力してください

次に、識別子を次のようにデキューと一致させる必要があります。

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

あるいは

nibを使用している場合は、クラスを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    
}

Appleの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、2015

@GertCuykens SwitchCellは私のカスタムUITableViewCellです
Dan Beaulieu

1
今はMacから離れていますが、家に帰ったら間違いなくアップデートできます。
Dan Beaulieu

1
それを置き換えることUITableViewCell.selfは私にとってはうまくいくようです。多分答えにメモを追加するかもしれません
ガート・カイケンズ

@GertCuykens指摘してくれてありがとう、UITableViewCell.selfのSwitchCell.selfを変更しました
Dan Beaulieu

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の両方で答えを説明します。

私たちが使用している場合はdequeueReusableCellWithIdentifier:forIndexPath:forCellReuseIdentifier::またはregisterClass:forCellReuseIdentifier:、我々はregisterNibを使用して、クラスやペン先のファイルを登録する必要があります方法として、このメソッドを呼び出す前に 、アップルDocumnetationは言います

追加します registerNib:forCellReuseIdentifier: or registerClass:forCellReuseIdentifier:

指定した識別子のクラスを登録し、新しいセルを作成する必要がある場合、このメソッドはinitWithStyle:reuseIdentifier:メソッドを呼び出してセルを初期化します。nibベースのセルの場合、このメソッドは提供されたnibファイルからセルオブジェクトをロードします。既存のセルが再利用できる場合、このメソッドは代わりにセルのprepareForReuseメソッドを呼び出します。

viewDidLoadメソッドでは、セルを登録する必要があります

目的C

オプション1:

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

オプション2:

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

上記のコードnibWithNibName:@"CustomCell"で、私のnib名CustomCellの代わりにnib名を指定してください

迅速

オプション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」(nr 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

ストーリーボードですべてを正しく設定し、クリーンビルドを実行しましたが、エラーが発生し続けました

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

エラーを修正しましたが、まだ困っています。私は「カスタムセル」を使用しておらず、テーブルビューが埋め込まれたビューを使用しています。ビューコントローラーをデリゲートおよびデータソースとして宣言し、セル識別子がファイル内で一致することを確認しました。何が起きてる?


1

これは、一部の人にとっては馬鹿げているように見えるかもしれませんが、私はそれを理解しました。このエラーが発生し、私にとっての問題は、静的セルを使用しようとしたが、動的にさらに追加したことでした。このメソッドを呼び出す場合、セルは動的プロトタイプである必要があります。ストーリーボードのセルを選択し、属性インスペクターの下で、最初に「コンテンツ」と表示されているため、静的ではなく動的なプロトタイプを選択する必要があります。


ありがとうございました!これはまさに私の問題でした。
イザヤターナー

1

ただ、回答のサプリメントは:あなたは右のすべてのものを設定した時間があるかもしれませんが、あなたが誤ってあなたにいくつかの他のUIを追加することも.xib同様に、UIButtonここに画像の説明を入力してください ちょうど余分なUIを削除し、それが動作します。


1

ストーリーボードのセルのCellIdentifier ==識別子であることを確認してください。両方の名前が同じです。これがあなたのためにうまくいくことを願っています


0

私の場合、私が電話したときにクラッシュが起こりましたdeselectRowAtIndexPath:

ラインは [tableView deselectRowAtIndexPath:indexPath animated:YES];

FIXED MY PROBLEMに変更し[self.tableView deselectRowAtIndexPath:indexPath animated:YES]; ます!

これが誰にも役立つことを願っています


0

Swiftでは、この問題は次のコードを

viewDidLoad

方法。

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

-1

このエラーに遭遇したbcセル再利用識別子が間違っていました-新人の間違いですが、それは起こります:1.セル再利用識別子にスペルミスや欠落文字がないことを確認します。2.同じように、大文字の数を忘れないでください。3.ゼロは「O」ではありません(Ohs)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.