ViewController не загружает подпредставления из nib в проекте ARC, работающем на iOS 4.3?
Моя команда недавно преобразовала довольно большой проект в ARC. Преобразование прошло хорошо, приложение работает и отлично работает на 5.0.
Проблема на 4.3. Любые контроллеры представления, созданные в коде с простым init, не загружают никакие подпредставления представления vc (это работает на 5.0)
Вот резюме:
Создайте контроллер представления с помощью [[MyViewController alloc] init]
, (Init-вызовы UIViewController initWithNibName:nil bundle:nil)
Это загружает перо с тем же именем, что и у View Controller (MyViewController.xib)
* Ожидается: перо создается как обычно со всеми подпредставлениями верхнего уровня и всеми выходами.
*Actual: создается перо, и устанавливается свойство view объекта MyViewController. Однако массив подпредставлений представления является пустым, и любые выходы к этим представлениям равны нулю, и представление представляется пустым, когда представлено
* Временное решение: создать экземпляр VC/load nib с помощью
[[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil]
Мне не удалось воспроизвести это в чистом проекте, начиная с ARC или переходя на ARC. Моя команда и я работаем над этим, но в то же время задались вопросом, не сталкивался ли кто-нибудь еще с этим и не нашел ли причину или триггер.
2 ответа
Последующее наблюдение в случае, если у кого-то еще есть эта проблема.
Поскольку мы поддерживаем 4.x и используем ARC, мы решили использовать MAZeroingWeakRef Майка Эша, чтобы получить слабый указатель в 4.x. В конце концов мы изолировали проблему достаточно, чтобы отследить ее до MAZeroingWeakRef. Мы опубликовали проблему в проекте MAZWR, и github и Майк объяснили, что происходит:
https://github.com/mikeash/MAZeroingWeakRef/issues/13
(По сути, MAZWR изменяет внутреннее имя класса VC на что-то вроде TestViewController_MAZeroingWeakRefSubclass. Инициализация VC зависит от этого имени класса для загрузки связанного с ним кончика - поэтому при его изменении он не может найти перо. Вызывая initWithNibName:bundle: и явно указав имя класса, соответствующий перо загружается правильно.)
Не уверен, что является причиной вашей проблемы, но если вы создаете общий базовый класс для всех ваших контроллеров представления, вы можете определить метод init следующим образом:
- (id)init
{
return [self initWithNibName:NSStringFromClass([self class]) bundle:nil];
}
Таким образом, вы можете гарантировать, что он загружает правильные кончики, не путая ваш код с повсеместным вводом явных имен кончиков.
Кстати, иногда мне приходилось использовать этот трюк с UITableViewControllers, так как их метод init, кажется, не соответствует соглашению.