Ответ 1
Это выглядит как ошибка для меня; ваш код должен быть в порядке. Если вы еще этого не сделали, укажите ошибку в http://bugreport.apple.com и приложите свой примерный проект.
Изменить. При дальнейшем изучении вашего образца проекта это не ошибка.
Переопределенный объект в вашем примере проекта не является экземпляром NSDate
. Вы можете полностью прокомментировать вызов tc.date = now
в своем примере проекта, и вы все равно увидите тот же крах. Фактически, вы можете полностью удалить материал NSDate. Перевыпущенный объект фактически является объектом TestVC
.
Вот что происходит.
В iOS 4.0, UIWindow
получил свойство rootViewController
. Если раньше вы просто вызывали [self.window addSubview:myRootcontroller.view]
при запуске приложения, это изменение теперь означало, что в окне действительно будет ссылка на контроллер корневого представления. Это важно для передачи уведомлений о ротации и т.д. В прошлом я полагаю, что UIWindow автоматически попытается установить rootViewController, когда было добавлено первое подвью (если оно еще не было установлено), но в вашем примере проекта, который явно не происходит. Это может быть связано с тем, как вы создаете представление, или может быть связано с изменением в iOS 5.0. В любом случае, это не было документированное поведение, поэтому вы не можете полагаться на это.
В большинстве случаев у вашего делегата приложения будет ivar, указывающий на контроллер корневого представления. Это не требуется строго, но обычно это происходит. Однако в представленном вами образце проекта диспетчер представлений не принадлежит делегату приложения. Вы также не установили его в качестве контроллера представления корневого окна. В результате в конце метода -application:didFinishLaunchingWithOptions:
ничего не осталось с сильной ссылкой на контроллер вида. Делегат вашего приложения не держится за него, и само окно не держится за него. Таким образом, ARC рассматривает его как локальную переменную (которая есть) и освобождает ее в конце метода.
Конечно, это не изменяет тот факт, что ваш UIButton
все еще имеет метод действия, нацеленный на ваш контроллер. Но, как указано в документации, -addTarget:action:forControlEvents:
не сохраняет цель. Таким образом, UIButton
имеет свисающую ссылку на ваш контроллер просмотра, который теперь освобожден, так как никто не имеет к нему ссылки. Отсюда сбой.
Исправление для этого - изменить эту строку в делетете приложения:
[self.window addSubview:tc.view];
:
self.window.rootViewController = tc;
С этим единственным изменением все теперь прекрасно работает.
Изменить. Также убедитесь, что параметр "Precheck code for ARC migration" не включен, так как это приведет к тому, что компилятор обработает код вручную, и это не приведет к правильному удержанию/release.