4

我已经阅读了 Apple 的“您的第一个 iOS 应用程序”指南,其中的所有内容对我来说似乎都一清二楚。然而,当我试图了解 XCode 中提供的基于视图的 iOS 应用程序模板如何工作时,我遇到了一些有趣的难题。

我知道应用程序从 *-Info.plist 文件中获取主 nib 文件名(通常是 MainWindow.xib)。我不明白的是,XCode 如何知道默认情况下哪个 nib 文件与使用此基于视图的应用程序模板创建的控制器相关联。在指南中,您从基于 Window 的应用程序开始,并且“必须编写”如下内容:

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

[self setMyViewController:aViewController];

这很有意义。然而,事实证明,在基于 View 的 iOS 应用程序模板中没有这样的东西,而且这个 nib 规范实际上并不是首先需要的,只要您创建 UIViewController 子类并使用选项“With XIB for user interface “检查。我的问题是,XCode 是如何知道哪个 nib 与该控制器相关联的,即它是将此连接存储在某些文件中,还是通过某种约定(也许控制器和 nib 文件的名称相同)?此外,“从“MyViewBasedAppController”加载的”字幕来自于 MainWindow.xib 中的 Interface builder 的控制器视图中的哪里?当我手动添加控制器时它肯定不存在,所以我很好奇 XCode 在我背后做了什么魔法,当我想我的时候

4

1 回答 1

6

如果您查看目标信息(双击目标以显示该信息),“属性”选项卡您将看到主要 Nib 文件的名称。出于这些目的,“Nib”和“Xib”这两个词是可以互换的;Xib 只是 Nib 的一个较新的替代品。

它将是模板中的“MainWindow”。如果您打开 MainWindow.xib,您会看到其中有一个名为“[项目名称] App Delegate”的对象,如果您显示检查器并在“i”选项卡下检查,您将看到类的类型是在顶部命名。如果您检查连接选项卡(向右箭头),您将看到文件所有者(即 UIApplication 本身)附加了它的“委托”属性。

您还会看到它有一个名为“viewController”的插座。它附加到 xib 中名为“[项目名称] 视图控制器”的另一个对象。检查它的类型,你会看到它是 Xcode 添加到项目中的视图控制器的类型。查看它的属性(检查器中的第一个选项卡,带有滑块图形),您还会看到一个单独的 nib 文件被指定为包含其主要细节。

为了论证起见,假设我将我的项目称为“NibTest”并且没有进行任何更改。

在运行时,设备会加载 Info.plist。在那里,它看到委托的类型是 NibTestAppDelegate。因此,它将实例化 NibTestAppDelegate 类的实例并将 UIApplication 的委托属性设置为它。

然后它将从 MainWindow.nib 中看到 NibTestAppDelegate 有一个名为 viewController 的成员,类型为 NibTestViewController。所以它将创建一个实例,并在它刚刚创建的 NibTestAppDelegate 实例上设置 viewController 属性。

这样做会打开另一个 xib 并继续执行相同的步骤。

Objective-C 有一个完全反射的运行时,所以你可以在运行时通过它们的类名来实例化对象。例如,这是 Objective-C 和 C++ 之间的差异之一。

Xcode 不生成任何隐藏代码或依赖任何隐藏的命名约定。整个事情是由操作系统在运行时计算出来的。

编辑:例如,代替您的示例:

    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 回答