0

在这一点上,我有一个相当简单的 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,为什么我还必须对所有内容进行类型转换?这是哈克吗?

4

2 回答 2

3

调用属性

window.rootViewController

返回 的实例UIViewController,并且该类没有名为 的公开可见属性delegateUINavigationController,但是,确实如此。

当使用属性语法(即点符号)时,编译器需要知道接收者的类声明了哪些属性。

如果您改为使用标准消息表示法并且不强制转换[rootViewController setDelegate:self],那么它可能会work,但我相信您仍然会收到编译器警告,但它会“工作”。

但通常最好是明确的。编译器不知道如何正确/安全地将消息发送-setDelegate:UIViewController,这就是它抱怨的原因。你需要更明确地处理它。

于 2012-05-08T03:52:54.780 回答
1

请记住,当您打电话时,self.window.rootViewController您实际上是在打电话

[self.window rootViewController];

这是一个返回 UIViewController 对象的方法。UIWindow Class 中声明的 rootViewController 属性属于 Class UIViewController

UIWindow 对象不知道它的 rootViewController 属性属于哪个类,因为设置属性实际上是在调用

[self.window setRootViewController:(UIViewController *) aViewController];

类型转换已经发生在这里。运行时还将使用此方法来实现您在 xib 中声明的出口链接。

所以没有办法,只能重新排版。相同的情况rootNavigationController.topViewController

于 2012-05-08T04:23:58.550 回答