簡體   English   中英

dequeueReusableCellWithIdentifier:forIndexPath 中的斷言失敗:

[英]Assertion failure in dequeueReusableCellWithIdentifier:forIndexPath:

所以我正在為我的學校制作一個 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-10-2014 13:05.357 Reader[4390:c07] *由於未捕獲的異常“NSInternalInconsistencyException”而終止應用程序,原因:“無法將帶有標識符 Cell 的單元格出列-必須為標識符注冊一個筆尖或類,或連接故事板中的原型單元格“*第一擲調用堆棧:(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]));
    }
}

請幫忙!

您正在使用dequeueReusableCellWithIdentifier:forIndexPath:方法。 該方法的文檔是這樣說的:

重要提示:在調用此方法之前,您必須使用registerNib:forCellReuseIdentifier:registerClass:forCellReuseIdentifier:方法注冊一個類或 nib 文件。

您沒有為重用標識符"Cell"注冊筆尖或類。

查看您的代碼,您似乎希望 dequeue 方法在沒有單元格給您時返回nil 您需要使用dequeueReusableCellWithIdentifier:來實現該行為:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

注意dequeueReusableCellWithIdentifier:dequeueReusableCellWithIdentifier:forIndexPath:是不同的方法。 前者后者見文檔。

如果您想了解為什么要使用dequeueReusableCellWithIdentifier:forIndexPath:請查看此問答

我認為這個錯誤是關於為標識符注冊你的筆尖或類。

這樣你就可以在你的 tableView:cellForRowAtIndexPath 函數中保留你正在做的事情,只需將下面的代碼添加到你的 viewDidLoad 中:

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

它對我有用。 希望它可以幫助。

雖然這個問題已經很老了,但還有另一種可能性:如果您使用的是 Storyboard,則只需在 Storyboard 中設置 CellIdentifier。

因此,如果您的 CellIdentifier 是“Cell”,只需設置“Identifier”屬性:在此處輸入圖片說明

確保在執行此操作后清理您的構建。 XCode 有時在 Storyboard 更新方面存在一些問題

我有同樣的問題替換

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

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

    }

解決了

問題是最有可能是因為你配置自定義UITableViewCell在故事板,但你不要用故事板實例化UITableViewController使用這種UITableViewCell 例如,在MainStoryboard,你有一個UITableViewController子類,稱為MyTableViewController並有一個自定義動態UITableViewCell稱為MyTableViewCell與識別ID“了myCell”。

如果您像這樣創建自定義UITableViewController

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

它不會自動為您注冊您的自定義 tableviewcell。 您必須手動注冊它。

但是如果你使用 storyboard 來實例化MyTableViewController ,像這樣:

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

好事發生了! UITableViewController將自動注冊您在故事板中為您定義的自定義 tableview 單元格。

在您的委托方法“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 將自動為您創建新單元。

然后你就完成了!

我將補充一點, Xcode 4.5包含新的dequeueReusableCellWithIdentifier:forIndexPath:
在其默認模板代碼中 - 對於期望較舊的dequeueReusableCellWithIdentifier:方法的開發人員來說,這是一個潛在的問題。

在您的故事板中,您應該將原型單元格的“標識符”設置為與您的 CellReuseIdentifier“單元格”相同。 然后您將不會收到該消息或需要調用該 registerClass: 函數。

Swift 2.0 解決方案:

您需要進入您的屬性檢查器並為您的單元格標識符添加一個名稱:

在此處輸入圖片說明

然后你需要像這樣使你的標識符與你的出隊匹配:

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    
}

Apples 的 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)

如果您要使用自定義靜態單元格,只需評論此方法:

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

並在故事板的“屬性檢查器”中為單元格提供一個標識符。

我在Objective C和Swift中都給了你答案。在那之前我想說

如果我們使用dequeueReusableCellWithIdentifier:forIndexPath: ,我們必須在調用此方法之前使用 registerNib:forCellReuseIdentifier: 或 registerClass:forCellReuseIdentifier: 方法注冊一個類或 nib 文件,如Apple文檔所說

所以我們添加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"給出你的筆尖名稱而不是我的筆尖名稱 CustomCell

迅速

選項1:

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

選項 2:

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

在上面的代碼中nibName:"NameInput"給出你的筆尖名稱

使用 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
}

我昨晚花了幾個小時弄清楚為什么我的編程生成的表在 [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 文件中聲明

FWIW,當我忘記在故事板中設置單元格標識符時,我遇到了同樣的錯誤。 如果這是您的問題,那么在故事板中單擊表格視圖單元格並在屬性編輯器中設置單元格標識符。 確保您在此處設置的單元格標識符與

static NSString *CellIdentifier = @"YourCellIdenifier";

我在情節提要中正確設置了所有內容並進行了干凈的構建,但一直收到錯誤“必須為標識符注冊一個筆尖或類或在情節提要中連接原型單元格

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

更正了錯誤,但我仍然不知所措。 我沒有使用“自定義單元格”,只是一個嵌入了 tableview 的視圖。 我已將視圖控制器聲明為委托和數據源,並確保單元格標識符在文件中匹配。 這里發生了什么?

我有同樣的問題,有同樣的錯誤,對我來說它是這樣工作的:

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

也許它對其他人有用。

這對某些人來說可能看起來很愚蠢,但它讓我着迷。 我收到了這個錯誤,我的問題是我試圖使用靜態單元格,但隨后動態添加了更多的東西。 如果您正在調用此方法,您的單元格需要是動態原型。 在故事板和屬性檢查器下選擇單元格,第一件事是“內容”,您應該選擇動態原型而不是靜態的。

只是對答案的補充:可能有一段時間您將所有事情都設置正確,但您可能會不小心在.xib添加一些其他 UI,例如UIButton 在此處輸入圖片說明 只需刪除額外的用戶界面,它就可以工作。

確保故事板中單元格的 CellIdentifier == 標識符,兩個名稱相同。 希望這對你有用

就我而言,崩潰發生在我調用deselectRowAtIndexPath:

該行是[tableView deselectRowAtIndexPath:indexPath animated:YES];

將其更改為[self.tableView deselectRowAtIndexPath:indexPath animated:YES]; 解決了我的問題!

希望這可以幫助任何人

在 Swift 中,這個問題可以通過在你的代碼中添加以下代碼來解決

查看已加載

方法。

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

您必須注意,在使用interface builder並創建包含一個單元格的Xib (nib) 時,還會創建一個placeholder ,該placeholder指向將要使用的類。 意思是,當您將兩個UITableViewCell放在一個 Xib 文件中時,您可能會遇到完全相同的問題,導致*** Assertion failure ... 占位符機制不起作用,然后會感到困惑。 而是將不同的占位符放在一個 Xib 中閱讀..

最簡單的解決方案(即使這看起來有點簡單)是一次將一個 Cell放在一個 Xib 中 IB 將為您創建一個占位符,然后所有工作都按預期進行。 但這會直接導致額外的一行代碼,因為這樣您就需要加載正確的 nib/xib 要求它所在的重用單元格。 所以下面的示例代碼集中在一個表視圖中使用多個單元格標識符斷言失敗很常見。

// possibly above class implementation
static NSString *firstCellIdentifier = @"firstCellIdentifier";
static NSString *secondCellIdentifier = @"secondCellIdentifier";

// possibly in -(instancetype)init 
UINib *firstNib = [UINib nibWithNibName:@"FirstCell" bundle:nil];
[self.tableView registerNib:firstNib forCellReuseIdentifier:firstCellIdentifier];
UINib *secondNib = [UINib nibWithNibName:@"SecondCell" bundle:nil];
[self.tableView registerNib:secondNib forCellReuseIdentifier:secondCellIdentifier];

在一個 UITableView 中使用兩個 CellIdentifier 的另一個問題是必須注意行高和/或節高。 兩個單元格當然可以有不同的高度。

注冊類以供重用時,代碼看起來應該有所不同。

當您的單元格位於 Storyboard 而不是 Xib 中時,“簡單的解決方案”看起來也大不相同。 注意占位符。

還要記住,界面構建器文件具有版本明智的變化,需要設置為您的目標操作系統版本支持的版本。 即使您可能很幸運,您放置在 Xib 中的特定功能自上一個 IB 版本以來沒有改變,也沒有拋出錯誤。 因此,使用 IB 制作的 Xib 設置為與iOS 13+兼容,但用於在早期版本iOS 12.4上編譯的目標中也會導致問題,並可能導致斷言失敗。

遇到這個錯誤 bc cell re-use identifier is wrong--一個新手錯誤,但它發生了: 1. 確保 cell re-use identifier 沒有拼寫錯誤或丟失的字母。 2. 同樣,不要忘記大小寫計數。 3. 零不是“O”(哦)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM