İçinde onaylama hatası - [UITableView _endCellAnimationsWithContext:]


89

Umarım bu hızlı bir çözüm olur. Sürekli aldığım hatayı anlamaya çalışıyorum. Hata aşağıda listelenmiştir ve uygulama bunun altındadır.

Herhangi bir yardım takdir edilmektedir.

Teşekkürler

2012-04-12 21: 11: 52.669 Chanda [75100: f803] --- içinde onaylama hatası -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1914.84/UITableView.m:1037 2012-04-12 21: 11: 52.671 Chanda [75100: f803] --- Yakalanmamış istisna nedeniyle uygulama sonlandırılıyor ' NSInternalInconsistencyException' , neden: 'Geçersiz güncelleme: Bölüm 0'da geçersiz satır sayısı. Güncellemeden (2) sonra var olan bir bölümde yer alan satırların sayısı, güncellemeden (2) önce o bölümde bulunan satır sayısına eşit olmalıdır, artı veya eksi o bölümden eklenen veya silinen satır sayısı (1 eklendi, 0 silindi) ve artı veya eksi o bölüme veya bu bölüme taşınan satır sayısı (0 içeri veya 0 taşındı). '

#import "AppDelegate.h"

@implementation AppDelegate

@synthesize window = _window;
@synthesize databaseName,databasePath; 

- (BOOL)application: (UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
    self.databaseName = @"Customers.db";

    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentDir = [documentPaths objectAtIndex:0];
    self.databasePath = [documentDir stringByAppendingPathComponent:self.databaseName];
    [self createAndCheckDatabase];

    return YES;
}

- (void)createAndCheckDatabase {
    BOOL success;

    NSFileManager *fileManager = [NSFileManager defaultManager];
    success = [fileManager fileExistsAtPath:databasePath];

    if (success) return; 

    NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:self.databaseName];

    [fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
}

@end

3
Bu kodu sınıflara taşımalı ve muhtemelen arka planda çalıştırmalısınız. Her neyse, bu hata genellikle tablo görünümünün veri kaynağı tarafından sağlanan satır sayısını gerçekten azaltmadan satırları kaldırmaya çalıştığınızda ortaya çıkar. Satırları kaldırdığınızda gerçekten verileri kaldırıyor musunuz? Herhangi bir satırı silmiyorsanız, tablo görünümü veri kaynağı uygulamasını sağlayabilir misiniz?
Constantino Tsarouhas

Yanıtlar:


43

Bize kodun bu bölümünü göstermenizin nedenini anlamıyorum. Hatanız, kodunuzda bu kısma bağlanmalıdır sanırım

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

Muhtemelen bu veri kaynağı yöntemlerinden birinde hata yapıyorsunuz. Şu anda tam olarak neyin yanlış olduğunu söylemek imkansız ama böyle bir şey olabilir varsayalım: Sen Tablo görünümünü anlatıyorsun numberOfRowsInSectionistiyorum size n satırlar ayrılmış ve kurulum ve cellForRowAtIndexPathsonra sadece idare n - 1 örneğin satırları.

Maalesef bu yanıt olması gerektiği kadar kesin olamaz. Bize veri kaynağınızın uygulandığını gösterirseniz, neler olduğunu anlatmak çok daha kolay olacaktır.


26

Sun Tzu'nun dediği gibi : Savaşmadan kazanmak en iyisidir . Benim durumumda bu tür bir hata mesajı gördüğümde (yani eklenen satırlar arasındaki tutarsızlık, silinmiş vb.) .. Hiçbir şeyde hata ayıklamam bile .. Satırları yeniden yüklediğimde fazladan arama yapmaktan kaçınıyorum. Bu% 99 bu hatanın meydana geldiği durumlar.

Bu, bu hatanın meydana geldiği yaygın bir senaryodur: Bir satırım var UINavigationControllerve bir var UITableView, bir satıra tıkladığımda yeni bir hata veriyor UITableViewve böyle devam ediyor. Bu hata her zaman sonuncuyu açtığımda ve ondan öncekine UITableviewgeri döndüğümde UITableViewoluyor, bu noktada loadIttemelde satırları ekleyen ve UITableView.

Ben yanlışlıkla benim loadIt işlevini yerleştirmek çünkü bu olur nedenidir viewDidAppear:animatedziyade viewDidLoad. viewDidAppear:animatedher UITableViewgörüntülendiğinde viewDidLoadçağrılır, yalnızca bir kez çağrılır.


3
Teşekkürler, iyi söyledin. İlk paragrafınız benzer bir sorunu çözmek için beni doğru yola soktu.
scrrr

2
benim için zevk @scrrr :)
abbood

Bu, bakış açımı değiştirdi - alakasız hale getirerek sorunu çözdü. Harikasın!
Charlie

ViewDidLoad yerine viewDidAppear'a sevindim. Bu benim sorunumdu ve haftalarca bununla uğraşıyordum.
GrandSteph

1
Sun Tzu alıntınızı yazdırdım ve ekranımın üstüne bantladım. Alıntı için teşekkür ederim ve bir ton gereksiz kod
Adrian

24

Satırları kaldırırken, güncelleme sırasında bölümleri de kontrol ettiğini unutmayın:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)theTableView

Bir bölümdeki son öğe olan bir satırı kaldırmak istiyorsanız bunun yerine tüm bölümü kaldırmanız gerekir (aksi takdirde bölüm sayımı yanlış olabilir ve bu istisnayı atabilir).


1
Bu gerçek altın! Çivi kafasına çarptı! Kesinlikle benim sorunum.
phatmann

6

NumberOfRowsInSection'ı belirleyen dizinizi güncellemeyi unutmayın. Canlandırmadan ve kaldırmadan önce güncellenmesi gerekiyor

Bölümdeki satır sayısının 1 olup olmadığını kontrol ediyoruz çünkü tüm bölümü silmemiz gerekecek.

Bu yanıtı daha açık hale getirebilecek biri varsa beni düzeltin.

[self.tableView beginUpdates];
if ([tableView numberOfRowsInSection:indexPath.section] == 1) {

   [tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationFade];
} else {

   [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
[self.tableView endUpdates];

4

Her bölüm elemanını ayrı dizilere koyuyorum. Sonra onları başka bir diziye (arrayWithArray) koyun. Bu problem için benim çözümüm:

[quarantineMessages removeObject : message];
[_tableView beginUpdates];
if([[arrayWithArray objectAtIndex: indPath.section] count]  > 1)
{
    [_tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indPath] withRowAnimation:UITableViewRowAnimationBottom];
}
else
{
    [_tableView deleteSections:[NSIndexSet indexSetWithIndex:indPath.section]
              withRowAnimation:UITableViewRowAnimationFade];
}
[_tableView endUpdates];

1
benim için onu çözen başlangıç ​​ve bitiş güncellemeleriydi, teşekkürler!
Mark W

2
Bölümün boşalacağını ve bunun yerine onu canlandırma ihtiyacını bilmiyordum ... Lanet olsun! Teşekkürler!
dvkch

1
Bu cevaptan çok yardım alarak çalışacak kodumu aldım. Aşağıya gönderiyorum.
love2script12

2

Ben de aynı hatayı aldım.

Şu satırları kullanıyordum

UINib *myCustomCellNib = [UINib nibWithNibName:@"CustomNib" bundle:nil];
[tableView registerNib:myCustomCellNib forCellReuseIdentifier:@"CustomNib"];

aynı sınıfla ilişkilendirilmiş farklı bir uca sahip olduğumdan, ucu viewDidLoad yöntemine kaydetmek için. Dolayısıyla çizgi

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"GBFBLoadingCell"];

ViewDidLoad'da ucu kaydetmediğim sürece sıfır dönüyordu.

Benim sorunum, "CustomNib.xib" ve "CustomNib ~ iphone.xib" dosyam için öznitelik denetçisinde tanımlayıcı ayarlamayı unutmamdı. (Daha doğrusu, tanımlayıcıyı XCode'daki öznitelik denetçisine yazdıktan sonra enter tuşuna basmayı unuttum, böylece yeni ad kaydedilemedi.)

Bu yardımcı olur umarım.


2
Cevabınızın konuyla bir ilgisi olduğunu sanmıyorum.
DawnSong

2

NSFetchedResultsControllerBenim gibi bir kullanıcı kullanıyorsanız ve arka planda veri güncelliyorsanız, temsilcide güncellemeleri başlatmayı ve bitirmeyi unutmayın:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView beginUpdates];
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView endUpdates];
}

2

Aynı hatayı aldım, denerken [tableView reloadData]iyi çalışıyordu. Hata aslında sıradaydı

[TabView insertRowsAtIndexPaths:indexPathsArray withRowAnimation:UITableViewRowAnimationRight];

İndexPath değerlerini kontrol etmeye çalıştığımda, gerektiği gibi doğru değillerdi.

Değerleri değiştirerek düzelttim indexPathsArray.

Bu yardımcı olur umarım .


1

UITableViewDataSourceProtokol yöntemlerinden biri olabilir

İçin

- tableView:numberOfRowsInSection:

toplamına veya sonucuna eşit bir tamsayı döndürmelidir

-insertRowsAtIndexPaths:withRowAnimation:ve / veya -deleteRowsAtIndexPaths:withRowAnimation:

İçin

- numberOfSectionsInTableView:

toplamına veya sonucuna eşit bir tamsayı döndürmelidir

-insertRowsAtIndexPaths:withRowAnimation: ve / veya -deleteSections:withRowAnimation:


0

Bir Çekirdek Veri tabanı ile aynı sorunu yaşadım. Çok sayıda FRC kullanıyorsanız, numberOfSectionsInTableView içindeki her koşulun içindeki tablo görünümünü yeniden yüklemeniz yeterlidir.


2
Ayrıca Core Data ile ilgili bu sorun var. Lütfen tarifinizi detaylandırır mısınız?
Drux

0

Bilgileri yönetmek için Swift ve FRC destekli bir veri deposu kullanırken bu benim başıma geldi. Geçerli indexPath.section'ı değerlendirmek için silme işlemine basit bir kontrol eklemek, gereksiz bir aramadan kaçınmamı sağladı. Sanırım bu sorunun neden oluştuğunu anlıyorum ... Temel olarak, veri setim boş olduğunda en üst sıraya bir mesaj yüklüyorum. Bu, sahte bir satır olduğu için bir defaya mahsus bir sayı oluşturur.

Çözümüm

... delete my entity, save the datastore and call reloadData on tableView
//next I add this simple check to avoid calling deleteRows when the system (wrongly) determines that there is no section.

       if indexPath.section > 0 {

        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .None)

            }

0

[YourTableView reloadData] öğesini çağırıp çağırmadığınızı kontrol edin; değerler dizisini değiştirdikten sonra.

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.