4

私はAppleの「あなたの最初のiOSアプリケーション」ガイドを読みましたが、そこにあるすべてのものは私には非常に明確に思えます。ただし、XCodeで提供されるViewベースのiOSアプリケーションテンプレートがどのように機能するかを理解しようとすると、いくつかの興味深い難問に遭遇します。

アプリケーションがメインのnibファイル名(通常はMainWindow.xib)を*-Info.plistファイルから取得することを理解しています。私が理解していないのは、XCodeは、このビューベースのアプリケーションテンプレートでデフォルトで作成されたコントローラーに関連付けられているnibファイルをどのように知るのかということです。このガイドでは、ウィンドウベースのアプリケーションから始めて、次のようなものを「作成する必要があります」。

MyViewController *aViewController = [[MyViewController alloc]
initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]];

[self setMyViewController:aViewController];

これは完全に理にかなっています。ただし、ビューベースのiOSアプリケーションテンプレートにはそのようなものはなく、オプション「ユーザーインターフェイスにXIBを使用」を使用してUIViewControllerサブクラスを作成した場合、そもそもこのペン先の仕様は実際には必要ありませんでした。 "チェックしました。私の質問は、XCodeはどのnibがこのコントローラーに関連付けられているかをどのように知るのか、つまり、この接続をいくつかのファイルに保存するのか、それともある種の規則(おそらくコントローラーとnibファイルの同じ名前)によって行うのかということです。さらに、「Loaded from "MyViewBasedAppController"」サブタイトルは、MainWindow.xib内のInterface Builderのコントローラーのビューのどこから来ていますか?コントローラーを手作業で追加した場合は絶対に存在しないので、XCodeが背後でどのような魔法を使っているのか興味があります。

4

1 に答える 1

6

ターゲット情報を見ると(ターゲットをダブルクリックして表示します)、[プロパティ]タブにメインのNibファイルの名前が表示されます。「Nib」と「Xib」という言葉は、これらの目的のために交換可能です。Xibは、Nibの新しい代替手段です。

テンプレートから新鮮な「MainWindow」になります。MainWindow.xibを開くと、「[プロジェクト名] App Delegate」というオブジェクトがあり、インスペクターを表示して「i」タブを確認すると、クラスのタイプが表示されます。上部に名前が付けられています。[接続]タブ(右向きの矢印)を確認すると、ファイル所有者(UIApplication自体)に'delegate'プロパティがアタッチされていることがわかります。

また、「viewController」というアウトレットがあることもわかります。これは、xib内の「[プロジェクト名]ViewController」という別のオブジェクトにアタッチされています。そのタイプを確認すると、Xcodeがプロジェクトに追加したViewControllerのタイプであることがわかります。その属性(インスペクターの最初のタブ、スライダーグラフィック付き)を見ると、別のnibファイルがその主要な詳細を含むものとして指定されていることもわかります。

議論のために、プロジェクトを「NibTest」と呼び、変更を加えなかったとします。

実行時に、デバイスはInfo.plistをロードします。そこでは、デリゲートのタイプがNibTestAppDelegateであることがわかります。そのため、クラスNibTestAppDelegateのインスタンスをインスタンス化し、UIApplicationのデリゲートプロパティをそれに設定します。

次に、MainWindow.nibから、NibTestAppDelegateにタイプNibTestViewControllerのviewControllerという名前のメンバーがあることがわかります。そのため、そのインスタンスを作成し、作成したばかりのNibTestAppDelegateインスタンスにviewControllerプロパティを設定します。

そうすることで、他のxibを開き、同じ種類の手順を続行します。

Objective-Cには完全にリフレクティブなランタイムがあるため、実行時にクラス名でオブジェクトをインスタンス化できます。これは、たとえば、Objective-CとC++の違いの1つです。

Xcodeは、隠しコードを生成したり、隠し命名規則に依存したりしていません。全体はOSによって実行時に理解されます。

編集:たとえば、あなたの例の代わりに:

    MyViewController *aViewController = [[MyViewController alloc]
initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]];

あなたは実際に行うことができます:

    MyViewController *aViewController = [[NSClassFromString(@"MyViewController") alloc]
initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]];

MyViewControllerがプログラムまたはより広いランタイムに存在する限り、これらは同じように動作します。

または、他の任意の文字列オブジェクトを渡すこともできますNSClassFromString。必要に応じてユーザーに依頼することもできます(ただし、セキュリティ上の理由から、これは非常に悪い考えです)。

于 2010-11-15T00:14:32.093 に答える