Странный сбой, связанный с перезагрузкой tableview

#iphone #objective-c #cocoa-touch #uitableview

#iPhone #objective-c #cocoa-touch #uitableview

Вопрос:

Я использую -reloadData только для перезагрузки моей таблицы, но по какой-то причине он выходит из строя каждый раз, когда мы загружаем эту таблицу. Это только одна из многих таблиц в приложении, обрабатываемых одним и тем же суперклассом view-controller:

 Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libobjc.A.dylib                     0x321effbc objc_msgSend   16
1   UIKit                               0x31abd9c4 -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:]   540
2   UIKit                               0x31abcaa2 -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow:]   1070
3   UIKit                               0x31abc22c -[UITableView layoutSubviews]   200
4   UIKit                               0x31a60d44 -[UIView(CALayerDelegate) layoutSublayersOfLayer:]   176
5   CoreFoundation                      0x36de4224 -[NSObject performSelector:withObject:]   36
6   QuartzCore                          0x317ab37a -[CALayer layoutSublayers]   210
7   QuartzCore                          0x317aaf92 CA::Layer::layout_if_needed(CA::Transaction*)   210
8   QuartzCore                          0x317af114 CA::Context::commit_transaction(CA::Transaction*)   220
9   QuartzCore                          0x317aee50 CA::Transaction::commit()   308
10  QuartzCore                          0x317a6d7e CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*)   50
11  CoreFoundation                      0x36e59b44 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__   12
12  CoreFoundation                      0x36e57d80 __CFRunLoopDoObservers   252
13  CoreFoundation                      0x36e580da __CFRunLoopRun   754
14  CoreFoundation                      0x36ddb4d6 CFRunLoopRunSpecific   294
15  CoreFoundation                      0x36ddb39e CFRunLoopRunInMode   98
16  GraphicsServices                    0x32ab6fe6 GSEventRunModal   150
17  UIKit                               0x31a8b73c UIApplicationMain   1084
  

Ни один из шагов в трассировке стека не взят непосредственно из нашего кода, так что я заблудился. Почему это может привести к сбою здесь?

Комментарии:

1. Когда вы перезагружаете таблицу? Например, в viewWillAppear или после загрузки некоторых данных и т. Д.

2. Я перезагружаю in -viewDidLoad, а затем, когда получаю уведомление «fetchedResultsControllerDidChangeContent».

3. Попробуйте установить NSZombieEnabled YES и посмотреть, пытаетесь ли вы получить доступ к выпущенному объекту. Возможно, это не связано с перезагрузкой данных tableview. Попытка доступа к выпущенному объекту воспроизводит аналогичные проблемы.

4. Если он работает с другими таблицами, я бы предположил, что он находится внутри данных или способа настройки ячеек методом cellForRowAtIndexPath.

5. Вы вызываете -reload из фонового потока вместо основного потока?

Ответ №1:

Убедитесь, что для делегата и источника данных вашего TableView установлено значение nil в методах dealloc ViewControllers. У меня было то же самое, когда система пыталась вызвать cellForRow …. для tableview, который был уничтожен.

Ответ №2:

Я столкнулся с этой идентичной трассировкой, используя перо для создания экземпляра ячейки строки, и обнаружил, что я случайно создал экземпляр ячейки из неверной ссылки на перо. Я создавал экземпляр ячейки следующим образом в обратном вызове cellForRowAtIndexPath для делегата источника данных таблицы:

 static NSString *CellIdentifier = @"CustomCellIdentifier";
CustomCell *cell = (CustomCell*)[aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) 
{
    [self.cellNib instantiateWithOwner:self options:nil];
    cell = tmpCell;
    self.tmpCell = nil;
}
  

Чтобы исправить, я убедился, что в viewDidLoad я создаю cellNib:

 self.cellNib = [UINib nibWithNibName:@"CustomCellNib" bundle:nil];
  

И в viewDidUnload удалите ссылку на него (это самый важный шаг):

 self.cellNib = nil;