为啥我似乎必须在 iOS 应用程序委托中键入 window.rootViewController?
Posted
技术标签:
【中文标题】为啥我似乎必须在 iOS 应用程序委托中键入 window.rootViewController?【英文标题】:Why do I seemingly have to typecast window.rootViewController in iOS app delegate?为什么我似乎必须在 iOS 应用程序委托中键入 window.rootViewController? 【发布时间】:2012-05-08 03:40:15 【问题描述】:此时我有一个相当简单的 ios 5 应用程序。
UINavigationController 被设置为 Interface Builder 中的初始视图控制器(我们仍然称它为 Interface Builder 吗?无论如何...)。 UINavigationController 有一个通用的 UITabBarController 作为它的 rootViewController。
我想将主 AppDelegate 用于 UINavigationController 和 UITabBarController 委托。我使 AppDelegate 符合 UINavigationControllerDelegate 和 UITabBarControllerDelegate。一切正常。但是!
在 AppDelegate 的 application:didFinishLaunchingWithOptions: 中,我觉得我在做一些 hacky。为了设置每个控制器委托,我必须对 self.window.rootViewController 和 self.window.rootViewController.topViewController 进行类型转换。
UINavigationController *rootNavigationController = (UINavigationController *) self.window.rootViewController;
UITabBarController *rootTabBarController = (UITabBarController *) rootNavigationController.topViewController;
[rootNavigationController setDelegate:self];
[rootTabBarController setDelegate:self];
如果我不进行类型转换 self.window.rootViewController 我无法设置它的委托。 topViewController (UITabBarController) 也一样。
如果我在 Inferface Builder 中声明初始视图是一个 UINavigationController,而不是一些通用的 UIViewController,我为什么还要对所有内容进行类型转换?这是 hacky 吗?
【问题讨论】:
你在尝试[self.window.rootViewController setDelegate:self]
时得到了什么?
"'UIViewController' 没有可见的@interface 声明选择器 setDelegate。"它不会编译。
【参考方案1】:
调用属性
window.rootViewController
返回UIViewController
的实例,并且该类没有名为delegate
的公开可见属性。但是,UINavigationController
可以。
当使用属性语法(即点表示法)时,编译器需要知道接收者的类声明了哪些属性。
如果您改为使用标准消息表示法而不进行转换,[rootViewController setDelegate:self]
,那么它可能会work
,但我相信您仍然会收到编译器警告,但它会“工作”。
但通常最好是明确的。编译器不知道如何正确/安全地将消息-setDelegate:
发送到UIViewController
,这就是它抱怨的原因。你需要更明确地处理它。
【讨论】:
嗯,有趣的是,我明确声明“初始视图控制器”是 InterfaceBuilder 中的 UINavigationController。这个声明与 self.window.rootViewController 无关吗? 不,它是绝对相关的。在 iOS 5 故事板中,初始视图控制器最终成为 UIWindow 实例中的rootViewController
。【参考方案2】:
请记住,当您拨打 self.window.rootViewController
时,您实际上是在拨打电话
[self.window rootViewController];
这是一个返回 UIViewController 对象的方法。
UIWindow 类中声明的rootViewController 属性属于UIViewController
类。
UIWindow 对象不知道它的 rootViewController 属性属于哪个类,因为设置属性实际上是在调用
[self.window setRootViewController:(UIViewController *) aViewController];
typecast 已经在这里发生了。运行时也会使用这个方法来实现你在 xib 中声明的出口链接。
所以没有办法,只能重新排版。
与rootNavigationController.topViewController
相同的情况
【讨论】:
以上是关于为啥我似乎必须在 iOS 应用程序委托中键入 window.rootViewController?的主要内容,如果未能解决你的问题,请参考以下文章