iOS - получение странной ошибки: нераспознанный селектор отправлен экземпляру в UITableView

Введение

В моем текущем приложении у меня есть UITableView, который содержит пользовательские объекты ячеек. Пользовательские объекты UIViewCellObject просто являются подклассами стандартного класса UITableViewCell. Пользовательские ячейки содержат информацию о запущенных фоновых загрузках и обновляют их с помощью таких вещей, как процент выполнения и т. д.

Пользовательские объекты ячейки прослушивают NSNotifications от процессов загрузки, работающих в фоновом режиме, и когда они получают соответствующее уведомление, они просто обновляют свои собственные элементы управления представлением новой информацией (например, процентом загрузки).

Теперь, когда процесс загрузки завершен, я переупорядочиваю массив активных объектов загрузки и перезагружаю табличное представление следующим образом:

-(void) uploadFinished: (NSNotification*)notification
{
    NSDictionary *userInfo = [notification userInfo];

NSNumber *uploadID = [userInfo valueForKey:@"uploadID"];

if (uploadID.integerValue == uploadActivity.uploadID)
{   
    [[ApplicationActivities getSharedActivities] markUploadAsFinished:uploadActivity];
    [parentTable reloadData];

    [self setUploadComplete];
}
}

Теперь этот метод имеет место в объектах tableviewcell, и, как вы можете видеть, они вызывают собственный UITableView для перезагрузки данных сразу после сортировки массива. Метод markUploadAsFinished просто переупорядочивает массив таким образом, что любая только что завершенная загрузка помещается вверху, и таким образом она будет отображаться в UITableView.

Проблема

Теперь проблема заключается в том, что при вызове этого метода я иногда получаю следующую ошибку: 'NSInvalidArgumentException', причина: '-[CALayer tableView:numberOfRowsInSection:]: нераспознанный селектор отправлено в экземпляр

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

Пользовательские ячейки загружаются из файла .NIB следующим образом:

    UploadCell *cell = [activeUploadsTable dequeueReusableCellWithIdentifier:@"UploadProgressCell"];

if (cell == nil)
{
    [[NSBundle mainBundle] loadNibNamed:@"UploadCellView" owner:self options:nil];

    cell = customCell;
}

Есть ли кто-нибудь, кто может иметь представление о том, что здесь происходит?

ИЗМЕНИТЬ

Прежде всего, я отследил, чтобы эта ошибка появлялась прямо в строке, где: reloadData

вызывается внутри пользовательских объектов ячеек.

Кроме того, кажется, что экземпляр, которому он отправляет методы, может измениться. Я тоже только что получил эту ошибку:

'NSInvalidArgumentException', reason: '-[UIScrollViewPanGestureRecognizer tableView:numberOfRowsInSection:]: unrecognized selector sent to instance

Я действительно понятия не имею, что здесь происходит.


person CodingBeagle    schedule 18.02.2012    source источник
comment
Где вы устанавливаете dataSource вашего табличного представления? Кажется, что он установлен на экземпляр CALayer, когда он терпит неудачу.   -  person Johannes Fahrenkrug    schedule 18.02.2012
comment
Источник данных табличного представления задается в файле .nib с именем ActiveUploads. Этот файл .nib просто содержит UIView, содержащий сам UItableview. Затем источник данных UITableView + делегат устанавливается владельцем файла .nib, а владельцем файлов является UIViewController, который обрабатывает создание, которое вы видели выше.   -  person CodingBeagle    schedule 18.02.2012
comment
Вы бегали с включенными зомби?   -  person rob mayoff    schedule 18.02.2012
comment
Возможно, это не связано с вашей проблемой, но стоит отметить: если у вас больше загрузок, чем ячеек помещается на одном экране, может не быть ячейки, отслеживающей загрузку, поэтому никто не будет вызывать markUploadAsFinished в объекте ApplicationActivities. Это может стать или не стать проблемой в будущем, в зависимости от того, что делает markUploadAsFinished.   -  person herzbube    schedule 18.02.2012
comment
Ах да, хороший улов, это может стать проблемой. MarkUploadAsFinished — это метод, который берет объект uploadActivity в точках и переупорядочивает его во внутреннем массиве uploads, чтобы он попадал в верхнюю часть табличного представления. Я не думаю, что есть какой-то реальный способ обойти это? Возможно, было бы лучше просто позволить ячейкам оставаться в исходном положении, чтобы не сбивать пользователя с толку, когда он смотрит на представление.   -  person CodingBeagle    schedule 18.02.2012


Ответы (2)


'-[CALayer tableView:numberOfRowsInSection:]: в экземпляр отправлен нераспознанный селектор

У вас плохой указатель. Похоже, что источник данных вашей таблицы освобождается, а таблица все еще существует. Таблица не сохраняет свой источник данных, потому что это может создать цикл сохранения. Если вы не позаботитесь о том, чтобы сохранить источник данных, пока таблица его использует, таблица может получить указатель на объект, которого больше не существует. В этом случае похоже, что объект CALayer впоследствии создается по тому же адресу. Когда позже таблица отправляет своему «источнику данных» сообщение о количестве строк, это сообщение доставляется на слой, который (очевидно) не имеет метода -tableView:numberOfRowsInSection:, и возникает ошибка.

person Caleb    schedule 18.02.2012
comment
Ага! Так вот причина! ну, как вы сказали, я понял, что причиной был плохой указатель, хотя я все еще не был уверен в основной причине, но это проясняет ситуацию :) Спасибо! - person CodingBeagle; 18.02.2012

По моему мнению, вы запускаете метод процесса загрузки в фоновом режиме, я думаю, что это другой поток, а не основной поток. И, насколько мне известно, когда вы имеете дело с объектами UIKIT, у вас происходит разрушение основного потока.

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

person Matrix    schedule 18.02.2012
comment
Спасибо, но я уже исправил эту проблему :) Я напишу об этом, как только Stackoverflow позволит мне ответить на мой собственный вопрос :) Это произошло не из-за проблем с потокобезопасностью, поскольку базовые объекты загрузки используют стандарт Асинхронный метод NSURLConnection, который занимается синхронизацией с основным потоком. - person CodingBeagle; 18.02.2012