Objective c 第二次调用loadView时,iOS 5未自动旋转视图

Objective c 第二次调用loadView时,iOS 5未自动旋转视图,objective-c,ios,uiviewcontroller,ios5,rotation,Objective C,Ios,Uiviewcontroller,Ios5,Rotation,当我在横向模式下运行应用程序时,第二次加载视图控制器的视图并调用loadView时,iOS 5不会将根视图控制器的视图从纵向旋转,也不会调用视图控制器的willRotate/willAnimateRotation/didRotate方法 如前所述,只有在卸载视图并且第二次调用loadView后才会发生这种情况。在我的应用程序中,我有时会先以编程方式卸载视图控制器的视图,然后再将其设置为根视图控制器。但是,当由于内存不足警告而自动卸载视图控制器的视图时,也会发生这种情况 这只发生在iOS 5上,而

当我在横向模式下运行应用程序时,第二次加载视图控制器的视图并调用
loadView
时,iOS 5不会将根视图控制器的视图从纵向旋转,也不会调用视图控制器的willRotate/willAnimateRotation/didRotate方法

如前所述,只有在卸载视图并且第二次调用
loadView
后才会发生这种情况。在我的应用程序中,我有时会先以编程方式卸载视图控制器的视图,然后再将其设置为根视图控制器。但是,当由于内存不足警告而自动卸载视图控制器的视图时,也会发生这种情况

这只发生在iOS 5上,而不是iOS 4.x上。它很容易在iOS模拟器中重现,下面是一个指向重现此问题的独立测试应用程序的链接:

要查看问题,只需编译应用程序并使用iOS 5.0模拟器在横向模式下启动它,然后点击“A”和“Back”,您将看到如何不发生旋转


有什么想法吗?这与我设置window.rootViewController的方式有关吗?

我通过它进行了调试,似乎在4.3和5.0之间发生了变化。在4.3 UIKit中调用
[UIWindow addRootViewController:
,在5.0中调用
[UIWindow setRootViewController:
。所以也许有些东西改变了,我们看不到

我建议通过not使用
[newController setupStuff]
(因此not将视图设置为nil),而不是覆盖

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    // do setup stuff here, reset content etc etc.
}
并在视图实际出现在屏幕上之前重置(已加载的)视图

其他信息:

a) 您不需要将视图设置为零。系统会帮你做到这一点。下次访问该视图控制器的view属性时,系统调用
loadView
重新创建视图:

如果访问此属性且其当前值为零,则视图 控制器自动调用loadView方法并返回 结果视图。默认的loadView方法尝试加载视图 从与视图控制器关联的nib文件(如果有)

b) 这一切归结为ios5中有关窗口
rootViewController
属性的行为。在iOS 5中,这两个方面并不等同:

 self.window.rootViewController = newController;
vs

前者完全忽略了方向,后者则没有

为了使事情变得更加复杂,如果一个人不覆盖加载视图,而是让系统自动创建一个空的UIView,并且只在视图中修改该视图,那么内存警告不会自动将视图设置为nil并释放它-docs:

魔法。取决于是否重写该方法。我真的无法用任何方式来测试这一点

案例1-覆盖的
loadView

触发内存警告将调用
didReceiveMemoryWarning
viewDidUnload

案例2-无
loadView

仅在模拟器中触发内存警告调用
didReceiveMemoryWarning
,但不调用
viewDidUnload

我会说,手动添加视图


干杯。

谢谢你的建议——但不幸的是,当系统将视图设置为nil(视图控制器响应内存不足警告)时,这不起作用。我明白了。尽管如此,我在测试时观察到,将视图设置为nil并在同一事件循环中切换rootViewController实际上导致了方向未传播到视图控制器的问题。仅在窗口中设置rootViewController不会引起任何问题。因此,也许使用
viewDidUnload
进行内存处理,并在
视图中执行其他操作会更好?@k:再次感谢。即使它们不在同一事件循环中发生(例如内存警告),这仍然是一个问题。我甚至不知道如何解决这个问题,因为这不仅仅是不调用旋转事件的问题——即使我手动调用它们,屏幕实际上也不会旋转。我不明白你在iOS 5中应该如何做到这一点。我今天再次关注你的问题,因为我真的很想弄清楚那里发生了什么(对于我自己的项目也是如此)。问题:可以重新创建整个视图控制器吗?还是保留它,然后重新创建视图?@k,看起来像是将
window.rootViewController=newController
更改为两行
removeFromSuperview
/
addSubview
修复了我的所有问题。奇怪,非常感谢你!
 [self.window.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
 [self.window addSubview:newController.view];
The default implementation releases the view only if it determines that it is safe to do so.