По вопросу «что мне делать с этим» может быть много ответов.
Более «формальный» способ предотвращения таких ошибок при разработке применяя дизайн по контракту в вашем коде. Это означает, что при разработке вы должны установить инварианты класса и / или даже предпосылки для функции и .
Короче говоря, инварианты класса гарантируют, что в вашем классе будут некоторые ограничения, которые не будут нарушены при нормальном использовании (и, следовательно, класс будет not получить в несогласованном состоянии). Предпосылки означают, что данные, данные как входные данные для функции / метода, должны соответствовать установленным ограничениям и никогда не нарушать их, а постулаты означают, что вывод функции / метода должен соответствовать установленным ограничениям снова не нарушая их. Условия контракта никогда не должны нарушаться во время выполнения программы без ошибок, поэтому дизайн по контракту проверяется на практике в режиме отладки, а отключен в выпусках , чтобы максимизировать развитую производительность системы.
Таким образом, вы можете избежать случаев NullReferenceException
, которые являются результатом нарушения установленных ограничений. Например, если вы используете свойство объекта X
в классе, а затем попытаетесь вызвать один из его методов, а X
имеет нулевое значение, то это приведет к NullReferenceException
:
public X { get; set; }
public void InvokeX()
{
X.DoSomething(); // if X value is null, you will get a NullReferenceException
}
Но если вы установите «свойство X никогда не должно иметь нулевого значения» в качестве предпосылки для метода, вы можете предотвратить описанный ранее сценарий:
//Using code contracts:
[ContractInvariantMethod]
protected void ObjectInvariant ()
{
Contract.Invariant ( X != null );
//...
}
По этой причине Код Контракт существует для приложений .NET.
В качестве альтернативы дизайн по контракту может быть применен с использованием утверждений .
ОБНОВЛЕНИЕ: Стоит отметить, что этот термин был придуман Бертраном Майером в связи с его дизайном языка программирования Эйфеля .
Попробуйте вставить новые строки вручную вместо [self.tableView reloadData]
:
[self.tableView beginUpdates];
for (int i = 0; i < responseArray.count; i++) {
_rowsNumber += 1;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
[self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationBottom];
}
[self.tableView endUpdates];
В методе dataSource return incremented int _rowsNumber
:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _rowsNumber;
}
Вы уверены, что после того, как пользователь вошел в систему и B выскочил, метод viewWillAppear
в A вызывается для того, чтобы выполнить обновление?
Если вы покажете B в качестве модального контроллера, при его увольнении вы не будете вызывать метод viewWillAppear
.
Насколько я знаю, viewWillAppear/viewDidAppear
(и другие подобные ему) являются событиями, генерируемыми UINavigationController в случае событий навигации (push / pop viewcontrollers). Так что, возможно, именно поэтому вы в конечном итоге получаете свое обновление, когда вы покидаете A и возвращаетесь ... все зависит от способа отображения следующего диспетчера представлений.
Это смущает и запутывает, но вот мое исправление.
Мой код:
_scanResultTable.delegate = self;
_scanResultTable.dataSource = self; // self's lifecycle was fine, wasn't getting released
[_scanResultTable reloadData];
Итак, странная часть: идентификатор _scanResultTable никогда не был объявлен в моем коде, в любом месте проекта. Я не знаю, как это скомпилировано (и я перекомпилировал несколько раз).
Моя основная причина заключалась в том, что я связал свой вывод таблицы с scanResultTable
в моем ViewController, но имел в виду его как _scanResultTable. Как только я начал использовать scanResultTable
, как я должен был, все прояснилось. Это заставляет меня задаться вопросом, имеет ли объектив-c что-то особенное в лидирующих символах подчеркивания в идентификаторах ...
Изменить: Это делает ! Хороший лорд, я не могу дождаться, когда никогда не коснусь этого языка.
Если вы используете другой источник данных, как и я, убедитесь, что вы сохраняете dataSource. Простое создание класса, которое будет источником данных и назначением его через tableView.dataSource = myDataClass
, будет недостаточным, поскольку свойство dataSource таблицыView будет слабым и будет выпущено при завершении viewDidLoad. Все другие методы вызывались для меня - даже, что удивительно, heightForRowAtIndexPath
- так что мне потребовалось некоторое время для отладки.
Если в представлении таблицы, который конфликтует с чем-то вроде Scrollview, он не вызывается. Вы должны отделить представления в своем раскадном файле или * .xib-файле.
// True
▼ View
► Table View
► Scrool View
► Constraints
// False
▼ View
► Scrool View
► Table View
► Constraints
я решил такую же проблему, проверив идентификатор tableViewCell. Перейдите к атрибутам İnspector и посмотрите раздел идентификатора. Наверное, отсутствует. Поэтому напишите идентификатор ячейки.
У меня такая же проблема, у меня есть та же проблема, что и в режиме просмотра таблицы внутри StackView и прокрутки табличного представления отключить и установить ограничение высоты, но после этого
tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
Не работает, прекратите вызывать этот метод все Data Source
и Delegate
, если у вас есть такая же проблема, что и решение. Таблица внизу, ведущий, конечный ограничитель
Ни один из ответов здесь не помог мне.
Я использовал программные программы, но забыл написать:
myTableView.translatesAutoresizingMaskIntoConstraints = false
Один правильный сценарий, по которому вызывается numberOfRowsInSection
, но cellForRowAtIndexPath
не будет вызываться, - это когда размер или позиционирование таблицы не требуют отображения строк.
Например, скажем, у вас была таблица высотой 20 пикселей, но заголовок для первого раздела был 30 высоким, и вы вернули nil для заголовка (или не реализовали viewForHeaderInSection
). В этом случае строки не будут отображаться, и это будет выглядеть так, как будто таблицы нет.
Я вижу, что вы используете IB. Размер таблицы может быть обманчивым в IB, поскольку он предполагает размеры заголовка и нижнего колонтитула. Я бы запустил фрейм для таблицы, чтобы вы понимали, где это происходит, когда выполняется приложение (в отличие от того, где оно появляется в IB). Я также был бы уверен в том, что вручную и поместите кадр таблицы перед вызовом reloadData. Это разрешит этот действительный случай, когда cellForRowAtIndexPath
не вызывается.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Make sure self.data isn't nil!
// If it is, you'll always return 0 and therefore
// cellForRowAtIndexPath will never get called.
return [self.data count];
}
Я использую ReactiveCocoa. Поэтому я создал модель для представления таблицы. Данные были подготовлены для отображения, поэтому numberOfRows
и так далее были вызваны. Но я не добавил tableview как subview, поэтому cellForRowAtIndexPath
не вызывался)))
У меня была такая же проблема, и проблема заключалась в том, что я пытался вызвать reloadData: из другого потока. Решение было бы:
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
Я использую источник данных клиента, и он был выпущен. Потому что это слабая ссылка на просмотр таблицы.
В этом же случае, но это была ошибка:
Я включил Scrollview с двумя таблицами внутри ViewController (требования к дизайну), в контроллере scrollview я создал программные средства ViewControllers (который содержит TableViews) и я использовал слабый var для его хранения, плохую идею, потому что они были выпущены в конце метода viewDidLoad.
Если вы не видите свой контент таблицы, проверьте, выпущен ли он.
Моя ошибка была очень болезненной для меня, потому что были вызваны все методы (delegate & amp; datasource), кроме viewForCell ...
Все говорят о высоте, но мой TableView
в StackView
с ведущим выравниванием заканчивается шириной 0.
Убедитесь, что ваш TableView
имеет правильный размер, используя Debug View Hierarchy
.