Xcode 如何通过故事板隐式设置 rootViewController?
Posted
技术标签:
【中文标题】Xcode 如何通过故事板隐式设置 rootViewController?【英文标题】:How does Xcode sets rootViewController implicitly via storyboard? 【发布时间】:2016-07-16 01:12:56 【问题描述】:带有 项目文件 和 Info.plist 的 Xcode 定位 main.storyboard 并找出初始 ViewController。但我希望在 AppDelegate 中为 ViewController 看到一些样板代码。
AppDelegate 看起来是空白的:(没有对 ViewController 的引用)
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
return YES;
...
@end
故事板是xml:
问题
Xcode 有什么 magic 代码来引用 storyboard xml 并找到控制器吗?
编译后,main() 会调出 AppDelegate,它应该直接引用 ViewController,或者有一个代理故事板对象来访问 ViewController。
我错过了什么?
【问题讨论】:
我认为这个问题增加了价值,答案令人惊叹。 【参考方案1】:我认为我的书(您已经找到)充分解释了这一点。 main
调用 UIApplicationMain()
并遵循一定的规则。如果你在 Info.plist 中指定了一个主故事板——而且你这样做了——那么:
UIApplication
将 初始视图控制器 实例(带有入口点箭头的那个)从情节提要中拉出。那是 ViewController 实例。
它还实例化 UIApplication 类。
它还实例化应用委托类(在 UIApplicationMain
调用中指定),并将其分配给 UIApplication 的 delegate
属性。
它创建一个窗口并将其分配给应用代理的window
属性,然后将该视图控制器分配给窗口的rootViewController
属性。
然后它显示窗口(并在应用委托上调用applicationDidFinishLaunching...
)。
这完全解释了启动过程。
【讨论】:
嗨,马特,你指的是哪本书。我很想了解这些点至少在高层次上是如何连接的。这个解释真的很有帮助。我找到了关于某些类的所有解释,但关于 Xcode 如何在应用程序中隐式发挥作用的解释不多。 apeth.com/iosBook/ch06.html 别再说 Xcode。 Xcode 没有任何作用。您使用 Xcode 编译和构建。您在运行时运行。运行时正在执行此操作。你知道,可可。您调用 UIApplicationMain,它就是这样做的。我不明白为什么这很难。三个不同的人已经告诉过你三次了。 感谢指正,Xcode 正在构建中。基于故事板的界面构建器起初看起来很神奇,而 UI 是由 Xcode 提供的,所以看起来就像它的 Xcode。【参考方案2】:一张图片值一千字。但是,这里有一个简短的描述:“它在你的项目的 settings/info.plist 中”。
在下图中,“Main”是我最初的故事板的名称。此外,初始视图控制器在界面构建器中有一个标志,上面写着“是初始视图控制器”,告诉它这是您希望首先运行的视图控制器。
附:点击图片放大它们:)
【讨论】:
嗨,布兰登,这真的很有帮助,并且在某种程度上回答了这个问题。我想了解构建过程中的控制流程。看起来 Info.plist 是应用程序的清单。我在哪里可以了解 xcode 如何在应用架构中导航以编译应用? XCode 只是一个 IDE/Build 系统。 Clang 是它用来编译你的应用程序的编译器。 发现这个apeth.com/iOSBook/ch06.html 解释得更深入一点。 (很有帮助) 问题仍然存在,因为 xcode 只是 IDE/Build 系统。为什么我们在 AppDelegate 中看不到 ViewController ?我会假设 Xcode 可以自动连接模板应用程序中的东西,以便我们扩展。归根结底,main() 是调用 AppDelegate 的入口点 - AppDelegate 中一定有一些东西知道 ViewController 吗? 我已更新问题以更好地反映问题。【参考方案3】:简短的回答是,Objective-C 的动态特性允许 UIApplicationMain()
仅从存储在应用程序的 info.plist
文件和主 NIB 或主 Storyboard 中的文本信息引导您的应用程序。编译器无需生成样板代码。
更长的答案:
UIApplicationMain 通过 Objective-C 运行时执行以下操作:
在所有情况下,UIApplicationMain()
都会在您的 plist 中实例化 NSPrincipalClass
键,通常是 UIApplication
,但可以是自定义子类。
在旧式无 NIB 应用程序中,UIApplicationMain()
将实例化在 main.m
中指定的 AppDelegate 类。它将 AppDelegate 连接到UIApplication
,然后交给 AppDelegate 来创建应用窗口、根视图控制器等。
在基于 NIB 的应用程序中,UIApplicationMain
不知道 AppDelegate 的名称。相反,它会加载您的主 NIB 文件 NSMainNibFile
,如 plist 中指定的那样。 NIB 负责实例化您的 AppDelegate 并连接到 UIApplication,以及创建您的主窗口和根视图控制器。
在 Storyboard 应用程序中,UIApplicationMain
实例化 NSPrincipalClass
和 main.m 中指定的应用程序委托,就像无 NIB 应用程序一样。然后它加载主故事板,它知道初始视图控制器是谁。它创建一个窗口,实例化初始视图控制器,并将其指定为窗口的根视图控制器。
【讨论】:
3代应用启动过程的精彩解释:)【参考方案4】:这就是它背后的原因:-
如果您删除该标记,您将看到一个空白屏幕。
【讨论】:
感谢您的回答,实际上我想知道 AppDelegate 是如何了解它的。 Xcode 只是一个 IDE。 我认为我无法解释其背后的过程,因为我也是一个初学者和学习者,但也许这会触发一些为初始视图创建方法的方法。 @YugalJindle以上是关于Xcode 如何通过故事板隐式设置 rootViewController?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 xcode 6.3 界面构建器故事板中默认模拟指标?
带有 XCode 4 的 MPVolumeView(故事板)