Сбой UITableView во время анимации, исправление найденного решения, но не находит причину, интересно, почему? - PullRequest
4 голосов
/ 01 апреля 2012

В моем проекте iphone я всегда вставляю UITableView в контроллер представления как IBOutlet, в большинстве случаев он работает хорошо, но происходит случайный сбой, когда анимация вызывается popToRootViewControllerAnimated. Отследите его по зомби, найдите, что сборы за аварийную остановку для экземпляра UITableView были освобождены, но по-прежнему отправляются системные события, поэтому происходит сбой.

Я всегда решаю такую ​​проблему любым из следующих методов в методе dealloc контроллера представления.

tableView.dataSource = nil;   (work for most cases)
or
[tableView removeFromSuperview]; (work for some special cases)

Хотя сбой можно исправить с помощью вышеуказанных изменений, но я все еще путаюсь.

  1. Является ли недостатком яблока то, что нам нужно явно установить для его dataSource значение nil, чтобы избежать сбоя? Или, может быть, наш собственный код приложения имеет проблемы?
  2. Кто-нибудь, кто также пережил такой сбой, вы знаете, в чем причина?

Любая идея или обсуждение будут оценены, спасибо заранее.

enter code here
Exception Type: EXC_BAD_ACCESS (SIGSEGV) 
Exception Codes: KERN_INVALID_ADDRESS at 0x626f6d37 
Crashed Thread: 0 

Thread 0 name: Dispatch queue: com.apple.main-thread 
Thread 0 Crashed: 
0 libobjc.A.dylib 0x33fe0c98 objc_msgSend + 16 
1 UIKit 0x364538f6 -[UITableView(UITableViewInternal) _spacingForExtraSeparators] + 58 
2 UIKit 0x3645337a -[UITableView(_UITableViewPrivate) _adjustExtraSeparators] + 158 
3 UIKit 0x36453218 -[UITableView layoutSubviews] + 40 
4 UIKit 0x363ff5f4 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 20 
5 CoreFoundation 0x30e13efc -[NSObject(NSObject) performSelector:withObject:] + 16 
6 QuartzCore 0x33d8dbae -[CALayer layoutSublayers] + 114 
7 QuartzCore 0x33d8d966 CALayerLayoutIfNeeded + 178 
8 QuartzCore 0x33d931be CA::Context::commit_transaction(CA::Transaction*) + 206 
9 QuartzCore 0x33d92fd0 CA::Transaction::commit() + 184 
10 QuartzCore 0x33d8c04e CA::Transaction::observer_callback(__CFRunLoopObserver*,     unsigned long, void*) + 50 
11 CoreFoundation 0x30e7da2e __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 10 
12 CoreFoundation 0x30e7f45e __CFRunLoopDoObservers + 406 
13 CoreFoundation 0x30e80754 __CFRunLoopRun + 848 
14 CoreFoundation 0x30e10ebc CFRunLoopRunSpecific + 224 
15 CoreFoundation 0x30e10dc4 CFRunLoopRunInMode + 52 
16 GraphicsServices 0x34efe418 GSEventRunModal + 108 
17 GraphicsServices 0x34efe4c4 GSEventRun + 56 
18 UIKit 0x36428d62 -[UIApplication _run] + 398 
19 UIKit 0x36426800 UIApplicationMain + 664 
20 ScoutFree 0x00099558 0x1000 + 623960 
21 ScoutFree 0x00003618 0x1000 + 9752

Ответы [ 2 ]

2 голосов
/ 19 августа 2013

Вы забыли установить tableView.delegate на nil, так что вы все равно можете получить сбои, особенно когда идет анимация (так как теперь запрашивается мертвый контроллер для новых строк).Это не недостаток Apple, это ответственность программиста, чтобы очистить эти ссылки.Так что установите dataSource и делегируйте свойства tableView на nil, затем отпустите tableview (установив соответствующее свойство на nil или выполнив iVar следующим образом [_iVar release]; iVar = nil;)

1 голос
/ 06 апреля 2012

Прежде всего, ЕДИНСТВЕННЫМИ вещами, которые вы должны вызывать в dealloc, является выпуск на ваших ivars, отмена регистрации для уведомлений NSNotificationCenter (если он зарегистрирован в init) или установка делегатов UIWebViews и UIScrollView на ноль (как предлагается в документации Apple). Если ваш UIViewController является делегатом / источником данных вашего табличного представления, нет необходимости устанавливать их в nil в dealloc (или где-либо еще), так как когда контроллер представления уничтожается, вы гарантированно не будете отправлять мошеннические сообщения, и Вы в равной степени гарантированы, что делегат / источник данных табличного представления не будет уничтожен раньше, чем табличное представление.

Весьма маловероятно, что дефект - это яблоки. На какую ОС вы ориентируетесь? Если вы используете ARC, у вас действительно должно быть несколько случаев, когда вам нужно дурачиться в dealloc. Если вы символизируете свой журнал сбоев, вы получите номера строк и классы из вашего приложения, которое вызывает сбой. Символизировать в Xcode 4 действительно просто, вы можете найти информацию об этом здесь: Символизирующие отчеты о сбоях в приложениях iPhone

Что значит, что вы всегда вставляете табличное представление как IBOutlet? Если это IBOutlet, это означает, что у вас есть табличное представление в nib-файле, и в этом случае табличное представление создается для вас, когда nib-файл выгружается. Если вы пытаетесь удалить табличное представление и повторно добавить его в представление с целью обновления его информации, это неправильный подход: простой вызов reloadData сделает это за вас, и снова выполните все методы делегата. , Является ли делегат и источник данных объектом ДРУГОЕ, чем контроллер представления, управляющий вашей таблицей?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...