0

首先,我昨天以不同的方式问了这个问题。经过更多的实验,我仍然不清楚“为什么”。我明白我需要做什么,但想弄清楚发生了什么。这是场景……</p>

我从一个干净的石板开始,一个单一的视图应用程序,只需将以下 NSLog 添加到 appDelegate ......</p>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSLog(@"%@",[self.window.rootViewController description]);

    return YES;
}

以上返回

<ViewController: 0x17e7dbf0>

现在,当我创建一个名为“TestViewController”(UIViewController 类型)的新类并将其分配给我的故事板中的控制器时,上面的 NSLog 返回

<TestViewController: 0x146594c0>

所以,我的问题是,“如果前面的描述显示 rootViewController 的类型是”TestViewController,为什么我需要类型转换(TestViewController *)?为什么我不能这样做……

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    TestViewController *tvc = self.window.rootViewController;
    return YES;
}

代替...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    TestViewController *tvc = (TestViewController*)self.window.rootViewController;
    return YES;
}

我想在这里消除迷雾。我错过了哪一块拼图?

谢谢你的帮助!

4

3 回答 3

1

In the second case you are telling the compiler that you know better. The return type of self.window.rootViewController is a UIViewController pointer. But you are trying to assign that to a pointer of type TestViewController. Without the cast, the compiler will warn you that it's not a proper assignment. By putting the cast in place, you are telling the compiler "trust me - I know that the view controller is really a TestViewController." Of course if it turns out you are wrong, you may or may not have issues during runtime.

In the first case, you are seeing the output from the actual class as the app is being run. The description method is returning the name of the actual class for the object as well as its address in memory.

Your two cases really have nothing to do with each other.

于 2013-07-20T23:25:19.610 回答
0

It's about being specific and working up or down the inheritance hierarchy.

In this case rootViewController is a UIViewController *, but you want it to be a subclass reference (TestViewController *). That can't be guaranteed by the compiler so you need to cast. The cast is basically you promising the compiler that at runtime it will work.

Say things were the other way around and rootViewController is a TestViewController *, but you want it to be a superclass reference (UIViewController *). In this case the compiler has enough information to guarantee that its true so you don't need to cast.

于 2013-07-20T23:24:49.947 回答
0

Because the compiler doesn't know jack about run-time types. It only knows about compilation-time types. Objective-C is a dynamic language which supports polymorphism, so objects declared with type T need not really be of type T. They can also be a subclass of T.

This is exactly what happens in your case. Since self.window.rootViewController is declared to be of type UIViewController, which is not a subclass of TestViewController (I suppose it's the other way around), you need the explicit type conversion, but you only need it to fool the compiler.

Casts don't really do anything in the context of Objective-C objects apart from silencing compiler warnings (they can have "interesting" side effects in case of other types in C, though), and the code would work just fine without the cast.

于 2013-07-20T23:26:00.250 回答