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

0

コンパイラは実行時の型についてジャックを知らないためです。コンパイル時の型についてのみ認識します。Objective-C はポリモーフィズムをサポートする動的言語であるため、 type で宣言されたオブジェクトはT実際には type である必要はありませんT。のサブクラスにすることもできますT

これはまさにあなたの場合に起こることです。is は のサブクラスではないself.window.rootViewControllertype であると宣言されているため(逆だと思います)、明示的な型変換が必要ですが、必要なのはコンパイラをだますためだけです。UIViewControllerTestViewController

キャストは、Objective-C オブジェクトのコンテキストでは、コンパイラの警告をサイレンシングする以外には何もしません (ただし、C の他の型の場合、「興味深い」副作用が生じる可能性があります)。コードは、キャストがなくても問題なく動作します。 .

于 2013-07-20T23:26:00.250 に答える