从故事板中快速初始化

Bre*_*ung 1 ios swift

我是一个快速的语言初学者,我有一个关于类初始化的问题.

当您使用空ViewController启动一个新项目时,如下所示:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }
 }
Run Code Online (Sandbox Code Playgroud)

由于它ViewController是一个子类,UIViewController并且它有一个指定的初始化器init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?).当你运行代码时,"谁"将参数放入初始化程序中?是故事板吗?

如果是这种情况,那么如果我在my ViewController中有一个存储属性需要一个指定的初始化程序来初始化我的存储属性,这将导致打破链上的初始化,这是否意味着故事板不再有义务初始化ViewController为了你?

Ger*_*ero 5

我知道这对初学者来说是误导性的,但在这种情况下,任何人都不会调用初始化程序.ViewController你谈到的实例是 storyboard文件中,这导致我将在一秒内进入的初始化路径.如果您以编程方式ViewController其他地方创建并从应用程序包中为其分配特定的nib,则可以使用您提到的方法.

各种模板都依赖于应用程序进程,最终由运行时系统在启动应用程序时完成:当应用程序启动时,它会查看它Info.plist以确定最初加载的故事板.在通常的各种Xcode模板中Main.storyboard(然后指定类型的初始视图控制器ViewController).你的项目不会有类似"生成代码"的东西,因为它是Application执行此操作的对象.在Objective-C项目中,您实际上可以看到这一点,因为入口点是常规的旧main方法(in main.m).Swift运行时没有显示它,它是您的应用程序使用的链接框架的一部分.

这么多的是,现在它理解故事板(为此事XIB文件)的工作方式是很重要的:他们是不是像"食谱",为应用程序创建一个使用常规指定的初始化程序的各种对象.它们实际上包含序列化形式的创建对象.这意味着当您编译应用程序时,ViewController会创建并"存档"到storyboard/xib中.此时,它无法知道storyboard/xib中与其他对象的各种连接,因为它正在构建所述故事板的过程中(这就是为什么你不能用插件做一些有意义的事情init,这些对象是尚未创建).只有在完成此创建和归档后,才会(还)将各种连接保存/添加到storyboard/xib中.

现在,如果您已编译的应用程序已启动且已加载Main.storyboard指定Info.plist的应用程序,则应用程序将从中取消归档初始视图控制器.为此,它不使用您提到的init方法ViewController,而是使用它的对应方法init(coder:).之后,它将各种出口和动作与从故事板(或更确切地说,场景)取消归档的其他相关对象连接起来.然后它加载视图,这会导致调用viewDidLoad.这也解释了为什么你只能对那里的故事板加载的视图控制器进行任何相关的初始化,而不是init.

现在,最后,问题是:您根本无法拥有依赖于在运行时调用的初始视图控制器的指定初始值设定项的属性.事实并非如此.这也是大多数ViewController实现没有覆盖的原因init,你几乎没有什么有意义的.您有三个选项可以初始化任何内容:

  1. 覆盖init(coder:).请注意,您不一定知道故事板或场景中的哪些其他对象尚未归档,并且尚未建立连接,因此您只能在此处执行不需要这些操作的内容.
  2. 实施awakeFromNib.对于在取消归档后从xib(和扩展故事板场景)加载的任何对象,以及与其他未归档对象的所有连接都会被调用.请注意,情况并非如此ViewControllers,因此不会从故事板中取消归档,而是在运行时以编程方式实例化.还有其他一些警告.
  3. 初始化所需的一切viewDidLoad.只有在ViewController实际加载视图时才会调用它(即通常在它即将显示的时候),但我猜这总是最终的情况.通常我会这样做.

如果您发现自己处于某种情况下,您必须在指定的初始化程序中初始化某些内容并想知道为什么在从故事板加载视图控制器时它会丢失,请不要忘记执行任何操作init,init(coder:)也可能执行encode(encoder:).我很少遇到这样的情况.为了更详细地解释何时以及如何完成这项工作,我需要您提供更多关于您认为必须完成的信息init.在我的头脑中,我可以想出添加到故事板场景的自定义视图(不是视图控制器),但这个答案已经足够长了......