DequeueReusableCellWithIdentifier içinde onaylama hatası: forIndexPath:


324

Bu yüzden okulum için bir rss okuyucu yapıyordum ve kodu bitirdim. Testi yaptım ve bana bu hatayı verdi. İşte bahsettiği kod:

- (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];

    }

İşte çıktıdaki hata:

2012-10-04 20: 13: 05.356 Okuyucu [4390: c07] * - [UITableView dequeueReusableCellWithIdentifier: forIndexPath:], /SourceCache/UIKit_Sim/UIKit-2372/UITableView.m:4460 2012-10-04 20: 13: 05.357 Okuyucu [4390: c07] * Yakalanmayan istisna 'NSInternalInconsistencyException' nedeniyle uygulamayı sonlandırma, nedeni: 'tanımlayıcı Hücreli bir hücreyi ayıklayamama - tanımlayıcı için bir uç veya sınıf kaydetmeli veya film şeridine bir prototip hücre bağlamalıdır ' * İlk atış çağrı yığını: (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: istisna atma adı verilen sonlandır

ve hata ekranında gösterdiği kod:

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

lütfen yardım et!


Yanıtlar:


488

dequeueReusableCellWithIdentifier:forIndexPath:Yöntemi kullanıyorsunuz . Bu yöntemin belgeleri şunu söylüyor:

Önemli: Bu yöntemi çağırmadan önce registerNib:forCellReuseIdentifier:veya registerClass:forCellReuseIdentifier:yöntemini kullanarak bir sınıfı veya uç dosyasını kaydetmeniz gerekir .

Yeniden kullanım tanımlayıcısı için bir uç veya sınıf kaydetmediniz "Cell".

Kodunuza baktığınızda, size verilecek nilbir hücresi yoksa dequeue yönteminin geri dönmesini beklersiniz . Bu dequeueReusableCellWithIdentifier:davranış için şunu kullanmanız gerekir :

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

Bildirim o dequeueReusableCellWithIdentifier:ve dequeueReusableCellWithIdentifier:forIndexPath:farklı yöntemlerdir. Doktor, bakın eski ve ikincisi .

Neden kullanmak istediğinizi anlamak istiyorsanız dequeueReusableCellWithIdentifier:forIndexPath:, bu soru-cevap bölümüne göz atın .


166
AMAN TANRIM. Neden bir UITableViewController için Xcode varsayılan şablonu size otomatik olarak dequeueReusableCellWithIdentifier: forIndexPath verir :? Çok yararsızdır.
spstanley

15
dequeueReusableCellWithIdentifer:forIndexPath:Eğer hücre nil olup olmadığını kontrol etmek gerekmez çünkü (iOS6 tanıtılan), güzel bir gelişmedir. (Buna UITableViewControllerbenzer şekilde çalışır UICollectionView) Ama evet, bu değişikliğin şablonda yorum yapmaması ve onaylama / kilitlenme mesajının daha yararlı olmaması can sıkıcı.
Jason Moore

2
En azından, implotding yerine UITableViewCell için varsayılan olacağını düşünürdünüz. Baka.
BadPirate

13
Bu cevabın son satırı altındır: Kullanmam dequeueReusableCellWithIdentifier:forIndexPath:gerektiğinde birden fazla ısırıldım dequeueReusableCellWithIdentifier:.
ele

Bu cevap mükemmel. Bir sorum var: benim ilk görünüm denetleyicisi olarak bir tableViewController var. DidSelectRow ... başka bir tableViewController gezinti yığını itiyorum. Neden sadece ilk tablo değil, ikinci tableViewController için bir hücre kaydetmek zorunda?
ArielSD

137

Bu hatanın uç veya sınıfınızı tanımlayıcıya kaydetmekle ilgili olduğunu düşünüyorum.

Böylece tablonuzda ne yaptığınızı koruyabilirsiniz ViewView: cellForRowAtIndexPath işlevi ve sadece viewDidLoad'ınıza aşağıdaki kodu ekleyin:

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

Benim için çalıştı. Umarım yardımcı olabilir.


3
Bununla küçük bir yakaladım - yeniden kullanım tanımlayıcısının, ilgili hücre için Storyboard ayarlarınızda belirlediğinizle eşleştiğinden emin olun.
James Boutcher

Sadece biraz farklı bir kullanım durumunda buna eklemek için, SplitViewController'ın Ana görünümünde bir satırı yeniden seçiyordum. Bu yeniden seçme satırı mantığı içindeydi viewDidLoadve bu mantığı düzeltmek için viewDidAppeartaşıdı.
Craig Conover

Hücreye giremedi == nil, Yani benim tableview hücresi her zaman sıfır.
Solid Soft

3
swift 3.0: self.tableView.register (UITableViewCell.classForCoder (), forCellReuseIdentifier: "Hücre");
norbDEV

68

Bu soru oldukça eski olmasına rağmen, başka bir olasılık daha var: Storyboard'ları kullanıyorsanız, Storyboard'da CellIdentifier'ı ayarlamanız yeterlidir.

CellIdentifier cihazınız "Cell" ise, "Identifier" özelliğini ayarlamanız yeterlidir: resim açıklamasını buraya girin

Bunu yaptıktan sonra yapınızı temizlediğinizden emin olun. XCode'un bazen Storyboard güncellemelerinde bazı sorunları var


3
harika, temizlik çok şey yapar! : D
Sandy

2
Not - "Hücre" dışında bir tanımlayıcı kullanırsanız, bu tanımlayıcıyı aşağıdaki satırda kullanmak için cellForRowAtIndexPath yönteminizi de değiştirmeniz gerekir: static NSString * CellIdentifier = @ "MyCellIdentifier";
gamozzii

5
Buna önemli bir ekleme: Tablo görünümü, "Statik Hücreler" DEĞİL "İçerik" özelliğinin "Dinamik Prototipler" olarak ayarlanmış olması gerekir
Ted Avery

Bu cevabın daha yüksek olması gerekiyor. Çok yararlı
Sukitha Udugamasooriya

Temizlik yapı Identifierözelliği güncellendikten sonra gerekli . Teşekkürler!
Crashalot

59

yerine aynı sorunu yaşadım

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

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

    }

çözülmüş


Teşekkür ederim. Bu sadece başım ağrıyor. =)
Robert

3
ipucu: - (id) dequeueReusableCellWithIdentifier: forIndexPath: kullanırsanız , hücrenin sıfır olup olmadığını doğrulamanız gerekmez. (IOS6>)
seufagner

sadece başım ağrıyor. =)
Abo3atef

26

Sorun büyük olasılıkla UITableViewCellfilm şeridinde özel yapılandırdığınız için , ancak bunu UITableViewControllerkullananları örneklemek için film şeridi kullanmamanızdır UITableViewCell. Örneğin, MainStoryboard'da, UITableViewControlleradlandırılmış bir alt sınıfınız MyTableViewControllerve "MyCell" tanımlayıcı kimliğiyle UITableViewCelladlandırılan özel bir dinamik sınıfınız var MyTableViewCell.

Özelinizi böyle oluşturursanız UITableViewController:

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

Özel tablo görünümü hücrenizi sizin için otomatik olarak kaydetmez. Manuel olarak kaydetmeniz gerekir.

Ancak MyTableViewController, örnek tahtasını örneklemek için kullanıyorsanız , şöyle:

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

Güzel bir şey olur! UITableViewControllerfilm şeridinde tanımladığınız özel tablo görünümü hücrenizi sizin için otomatik olarak kaydeder.

Temsilci yönteminiz "cellForRowAtIndexPath", tablo görünümü hücresini aşağıdaki gibi oluşturabilirsiniz:

- (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, geri dönüşüm sırasında yeniden kullanılabilir hücre yoksa sizin için otomatik olarak yeni hücre oluşturur.

O zaman işiniz bitti!


instantiateViewControllerWithIdentifierBenim viewController başlatmak için kullanarak ipucu günümü kurtardı!
Lei Zhang

günümü kurtardı: prototip hücreler bir tablo ile komşu
VC'deydi

Benim durumumda makul sebep bu.
Nora Alnashwan

19

Sadece ekleyeceğiz Xcode 4.5 yeni içerir dequeueReusableCellWithIdentifier:forIndexPath:
yaşlı bekliyor geliştiriciler için potansiyel bir gotcha - varsayılan şablon kodunda dequeueReusableCellWithIdentifier:yöntemi.


Beni soktu! Şimdi daha iyi bileceğim. ;)
spstanley

18

Film şeridinizde, prototip hücrenizin "Tanımlayıcısını" CellReuseIdentifier "Cell" ile aynı olacak şekilde ayarlamanız gerekir. O zaman bu mesajı alamazsınız veya bu registerClass: fonksiyonunu çağırmanız gerekmez.


2
Anladım! '100 upvotes' düğmesi nerede. Gerçek çözüm budur.
Jojo.Lechelt

Bir storyboard'a yeni bir tableView eklemenin sizin için varsayılan bir tanımlayıcı - 'Hücre' sağlayacağını düşünürsünüz. Özellikle tableView: cellForRowAtIndexPath!
ushika

18

Swift 2.0 çözümü:

Özellik Denetçinize gitmeniz ve hücreleriniz için bir ad eklemeniz gerekir Tanımlayıcı:

resim açıklamasını buraya girin

Ardından tanımlayıcınızı bu gibi sıhhatinizle eşleştirmeniz gerekir:

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

alternatif olarak

Bir uçla çalışıyorsanız, sınıfınızı cellForRowAtIndexPath'e kaydetmeniz gerekebilir:

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'in UITableView Sınıfı Referansı şöyle diyor:

Herhangi bir hücreyi ayıklamadan önce, tablo görünümüne nasıl yeni hücreler oluşturulacağını anlatmak için bu yöntemi veya registerNib: forCellReuseIdentifier: yöntemini çağırın. Belirtilen türde bir hücre şu anda yeniden kullanım kuyruğunda değilse, tablo görünümü otomatik olarak yeni bir hücre nesnesi oluşturmak için sağlanan bilgileri kullanır.

Daha önce aynı yeniden kullanım tanımlayıcısına sahip bir sınıf veya uç dosyası kaydettiyseniz, cellClass parametresinde belirttiğiniz sınıf eski girdinin yerine geçer. Sınıfın belirtilen yeniden kullanım kimliğinden kaydını silmek istiyorsanız, cellClass için nil belirtebilirsiniz.

İşte Apples Swift 2.0 çerçevesinden kod:

// 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)

Nereden SwitchCell.selfgeldiğini anlamıyorum ?
Gert Cuykens

@GertCuykens SwitchCell benim özel UITableViewCell
Dan Beaulieu

1
Şu anda Mac bilgisayarımdan uzaktayım, ancak eve geldiğimde kesinlikle güncelleyebilirim.
Dan Beaulieu

1
Yerine UITableViewCell.selfkoymak benim için işe yarıyor gibi görünüyor. Belki de cevaba bir not ekleyin
Gert Cuykens

@GertCuykens bunu işaret ettiğiniz için teşekkürler, UITableViewCell.self için SwitchCell.self değiştirdim
Dan Beaulieu

3

Özel Statik Hücreler ile gidiyorsanız sadece bu yöntemi yorumlayın:

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

ve hücrelere film şeridindeki "Özellik Denetçisi" nde bir tanımlayıcı verin .


3

Size hem Hedef C hem de Swift'te cevap veriyorum.

Kullandığımız takdirde dequeueReusableCellWithIdentifier:forIndexPath:forCellReuseIdentifier: biz registerNib kullanarak bir sınıf veya uç dosyasını kaydetmeniz gerekir veya RegisterClass: forCellReuseIdentifier: yöntemi bu yöntemi çağırmadan önce olduğu gibi Apple Documnetation Says

Bu yüzden ekliyoruz registerNib:forCellReuseIdentifier: or registerClass:forCellReuseIdentifier:

Belirtilen tanımlayıcı için bir sınıf kaydettikten ve yeni bir hücre oluşturulması gerektiğinde, bu yöntem initWithStyle: reuseIdentifier: yöntemini çağırarak hücreyi başlatır. Uç tabanlı hücreler için, bu yöntem sağlanan nesne ucundan hücre nesnesini yükler. Varolan bir hücre yeniden kullanılmak üzere kullanılabiliyorsa, bu yöntem hücrenin readyForReuse yöntemini çağırır.

viewDidLoad yönteminde hücreyi kaydetmeliyiz

Hedef C

SEÇENEK 1:

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

SEÇENEK 2:

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

yukarıdaki kodda nibWithNibName:@"CustomCell"benim uç adı CustomCell yerine uç adınızı verin

SWIFT

SEÇENEK 1:

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

SEÇENEK 2:

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

yukarıdaki kodda nibName:"NameInput"uç adınızı verin


3

Swift 3.0 ile çalışma:

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

Dün gece neden programlı olarak oluşturulan tablom [myTable setDataSource: self]; Yorum ve boş bir tablo kadar haşhaş Tamam, ama veri kaynağına ulaşmak için çalıştığım her zaman çöktü;

Temsilciyi h dosyasında ayarladım: @interface myViewController: UIViewController

Benim uygulama veri kaynağı kodu vardı ve hala BOOM !, her zaman çöküyor! "Xxd" (nr 9) 'e TEŞEKKÜR EDERİZ: bu kod satırını eklemek benim için çözdü! Aslında bir tabloyu bir IBAction düğmesinden başlatıyorum, işte tam kodum:

    - (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;
   }

Bu arada: popover'ı ona bağlamak istiyorsanız, düğme bir IBAction ve IBOutlet olarak bağlanmalıdır.

UIPopoverController * popoverController3, {} arasında @interface'ten hemen sonra H dosyasında bildirilmiştir


2

FWIW, film şeridinde hücre tanımlayıcısını ayarlamayı unuttuğumda aynı hatayı aldım. Sorununuz buysa, film şeridinde tablo görünümü hücresini tıklayın ve özellikler düzenleyicide hücre tanımlayıcısını ayarlayın. Burada ayarladığınız hücre tanımlayıcısının ile aynı olduğundan emin olun.

static NSString *CellIdentifier = @"YourCellIdenifier";

2

Ben aynı sorunu vardı, aynı hatayı vardı ve benim için böyle çalıştı:

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

Belki başka biri için yararlı olacaktır.


2

Ben kurulum Film Şeridi'nde doğru şeyi ve temiz bir yapı yaptım ama "hatası alan tuttu tanımlayıcı için bir kalem ucu veya bir sınıf kaydetmek veya film şeridindeki bir prototip hücresini bağlamak gerekir "

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

Hata düzeltildi, ancak hala kaybım var. Bir 'özel hücre' kullanmıyorum, yalnızca bir tableview katıştırılmış görünümü. Viewcontroller delege ve veri kaynağı olarak ilan ettim ve hücre tanımlayıcısının dosyada eşleştiğinden emin oldum. Burada neler oluyor?


1

Bu bazı insanlar için aptalca görünebilir ama beni yakaladı. Bu hatayı alıyordum ve benim için sorun, statik hücreleri kullanmaya çalışıyordum, ancak daha sonra dinamik olarak daha fazla şey ekliyordu. Bu yöntemi çağırıyorsanız, hücrelerinizin dinamik prototipler olması gerekir. Film şeridindeki ve Özellikler denetçisinin altındaki hücreyi seçin, ilk şey 'İçerik' der ve statik olmayan dinamik prototipleri seçmelisiniz.


TEŞEKKÜR EDERİM! Bu benim sorunumdu.
Isaiah Turner

1

Sadece cevapların bir eki: Her şeyi doğru bir şekilde ayarladığınız bir zaman olabilir, ancak yanlışlıkla aşağıdakilere .xibbenzer başka arayüzler de ekleyebilirsiniz UIButton: resim açıklamasını buraya girin Ekstra kullanıcı arayüzünü silin, işe yarar.


1

Bir film şeridindeki hücrenin CellIdentifier == tanımlayıcısının her iki adın da aynı olduğundan emin olun. Umarım bu senin için çalışır


0

Benim durumumda, aradığımda kaza oldudeselectRowAtIndexPath:

Çizgi [tableView deselectRowAtIndexPath:indexPath animated:YES];

Bunu değiştirme [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; SABİT MY PROBLEM!

Umarım bu herkese yardımcı olur


0

Swift'te bu sorun, aşağıdaki kod eklenerek çözülebilir.

viewDidLoad

yöntem.

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

-1

Bu hatayla karşılaştık bc hücresi yeniden kullanım tanımlayıcısı yanlıştı - bir çaylak hatası ama olur: 1. SURE hücresini yeniden kullanım tanımlayıcısının yazım hataları veya eksik harfleri yok. 2. Aynı hat boyunca, büyük / küçük harf sayımlarını unutmayın. 3. Sıfırlar "O" lar değildir (Ohs)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.