2015-01-09 3 views
0

У меня есть один ViewController, который принимает объекты от CoreData и строит с ними UITableView. Когда пользователь нажимает строка, я получаю объект репортажа и передать его на следующий контроллер представления с использованием:ARC. Object from array points to nil

Reportage *reportage = [self.reportages objectAtIndex:indexPath.row]; 
[self.tableView deselectRowAtIndexPath:indexPath animated:YES]; 
ReportageTeaserPanelViewController *rightController = (ReportageTeaserPanelViewController*)self.menuContainerViewController.rightMenuViewController; 
rightController.reportage = reportage; 
[self.menuContainerViewController toggleRightSideMenuCompletion:nil]; 

Переменная репортажа объявлена ​​как сильна в контроллере ReportageTeaserPanelViewController.

Проблема заключается в следующем. Если мне нужно перезагрузить асинхронно объекты в массиве родительского контроллера представления из-за наличия обновления в моей веб-службе, репортаж переменной будет равен нулю в контроллере ReportageTeaserPanelViewController. Я думал, что при использовании сильной ссылки контроллер ReportageTeaserPanelViewController должен сохранять «старый» объект репортажа, хотя он исчезает из массива.

Есть ли объяснения этого поведения?

Благодаря

+1

Если 'reportage' равен нулю после выполнения первого утверждения выше, это потому, что' self.reportages' равен нулю. Также возможно, конечно, что вы никогда не устанавливаете 'rightController.reportage', потому что' rightController' равен нулю. –

ответ

1

Из того, что я могу собрать, вы начинаете с self.reportages не является нулевым, но так как он перезагружается асинхронно после той начальной загрузки, когда пользователь выбирает таблицу во время выполнения асинхронной перезагрузки, вы в опасности self.reportages быть нулевой или потенциально неполный.

Для предотвращения инициализации вашего локального reportage переменного с нулевой стоимостью, я рекомендовал бы НЕ непосредственно перезагрузить свой self.reportages массив в асинхронном блоке в контроллере родительского вида, но вместо того, чтобы создать локальный массив внутри этого блока, а затем, как только что массив содержит полное и правильное содержимое, установив self.reportages, чтобы содержать содержимое этого локального массива. Таким образом, пока ваш веб-сервис вернет правильный «репортаж», self.reportages никогда не будет равен нулю.

0

Я думал, что с помощью сильной ссылки, контроллер ReportageTeaserPanelViewController должен держать «старый» объект репортажа.

Сильные ссылки неуязвимы. Ничто в этом коде не «сохраняется» - это все локальные автоматические переменные, поэтому они исчезают, как только код запускается. Только persistent ссылки могут сделать объект упорным. Экземпляр переменной/свойство является примером постоянной ссылки; он живет до тех пор, пока сам экземпляр, если, конечно, вы не измените его значение. Итак, место для поиска - это переменная экземпляра, reportages.

Вы говорите:

Reportage *reportage = [self.reportages objectAtIndex:indexPath.row]; 

Если нет объекта по этому индексу, нет ни одного объекта по этому индексу. Он не имеет ничего общего с сильными ссылками. Вам нужно подумать о том, где должно быть значение reportages.

Это звучит из вашего использования слова «асинхронно», как если бы вы могли устанавливать reportages в другом потоке и, возможно, на самом деле позже этого кода. Это будет проблемой. Вам нужно разобраться в настройке потока и порядке событий.

+0

Но экземпляр «ReportageTeaserPanelViewController» все равно должен иметь ссылку на «репортаж», даже если массив опустел. –

+0

@AaronBrager Но его код перезаписывает эту ссылку с помощью nil. – matt

+0

Объект находится в индексе, когда я заставляю его запускать ReportageTeaserPanelViewController. Но затем, асинхронно, я перезагружаю массив в родительском объекте, который заставляет объект в ReportageTeaserPanelViewController быть нулевым. – xger86x