0

First off, I asked this question in a different way yesterday. After more experimenting I'm still unclear as to the "WHY." I understand what I need to do but want to get clear on what's happening. Here's the scenario…

I'm starting with a clean slate, a single view application and simply adding the following NSLog to the appDelegate …

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

    return YES;
}

The above returns

<ViewController: 0x17e7dbf0>

Now, when I create a new class named "TestViewController" (of type UIViewController) and assign it to the controller in my storyboard, the above NSLog returns

<TestViewController: 0x146594c0>

So, my question is, "If the previous description shows the rootViewController to be of type "TestViewController, why do I need to typecast (TestViewController *)? Why can't I do this…

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

instead of...

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

I'd like to clear up the fog here. What piece of the puzzle am I missing?

Thanks for your help!

Lucas
  • 3,376
  • 6
  • 31
  • 46

3 Answers3

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.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
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.

Wain
  • 118,658
  • 15
  • 128
  • 151
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.

  • OK first, thank you ALL for your help here. Let me see if I have this right. This is just to satisfy the compiler (which doesn't know what I want to do with the type until runtime). Not unlike @Class forward declaration to keep the compiler happy. Is that about right? – user2502232 Jul 21 '13 at 01:18
  • @user2502232 Yes, something like that. –  Jul 21 '13 at 05:53