基于视图的 iOS 应用程序模板

Posted

技术标签:

【中文标题】基于视图的 iOS 应用程序模板【英文标题】:View-based iOS application template 【发布时间】:2010-11-14 23:54:54 【问题描述】:

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

我了解应用程序从 *-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 中的界面构建器视图中的控制器?当我手动添加控制器时它肯定不存在,所以我很好奇XCode在我背后做了什么魔术,当我认为我只是选择一个简单的代码模板时。

【问题讨论】:

【参考方案1】:

如果您查看目标信息(双击目标以显示该信息),“属性”选项卡您将看到主要 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。如果您愿意,甚至可以向用户索取(尽管出于安全原因,这将是一个非常糟糕的主意)。

【讨论】:

整个过程的精彩讲解,点赞。 嗯,你完全正确地用名字来实例化类,但这不是我问的。你在这里说什么:“这样做会打开另一个 xib 并继续执行相同的步骤。”似乎没有回答我的问题:如何解决 NibTestViewController 控制器的 nib 文件就是 NibTestViewController.xib 文件?换一种说法,怎么知道在这种情况下甚至应该有任何 nib 文件来加载(因为我们可以清楚地实例化没有 nib 文件的控制器)? "...查看其属性(检查器中的第一个选项卡,带有滑块图形),您还将看到一个单独的 nib 文件被指定为包含其主要详细信息“-对不起,我读到这里真的很累。这个答案真的很到位,非常感谢! 我尝试在 MainWindow.xib 中使用 NibTestViewController 没有在“属性”下指定“NIB 名称”,它仍然加载正确的视图(来自 NibTestViewController.xib 的视图)。即使我将文件名更改为 NibTestViewControllerObscureMe.xib,它也能正常工作。 iOS still 如何知道哪个 nib 文件与此控制器相关联?在这种情况下,它是否可能会遍历项目中的所有 nib,直到在“IBPartialClassDescription”中找到具有正确“className”的那个? 你确定它实际上是从第二个笔尖加载任何东西吗?它会知道从第一个类中创建什么样的类 - 第二个只包含适当的细节。

以上是关于基于视图的 iOS 应用程序模板的主要内容,如果未能解决你的问题,请参考以下文章

基于页面的应用程序和基于视图的应用程序之间的区别

基于页面的 App,UINavigation 控制器,类似于 iOS 日历

UI 模板视图 - iOs 应用程序上所有场景中的通用 UI 元素?

Objective C / IOS5 - 根视图 - 从空应用程序模板构建 (XCODE)

在 iOS 中以编程方式生成视图

我可以更改基于类的视图的模板搜索行为吗?