第4章介绍过获取实例的方式。可以直接实例化一个对象类型:
let v = UIView
也可以获取对已有实例的引用:
let v = self.view.subviews[0]
不过还有第3种方式:可以加载nib。nib是个特殊格式的文件,文件中是一些用于创建与配置实例的指令。加载nib实际上就是告诉nib遵循这些指令:它会创建并配置这些实例。
刚才提到的UIView实例就适合于使用这种方式创建,因为UIView常常都是通过nib创建的。我们在Xcode中通过图形化界面来编辑nib,就像绘图程序一样。其想法是设计一些界面对象(几乎都是UIView与UIView子类的实例),当应用运行时会使用到这些对象。当应用运行时,当真正开始需要这些界面对象时(通常是要在可视化界面中将其显示出来),你会加载nib,nib加载过程会创建并配置实例,你会接收到这些实例并将其添加到应用的界面中。
创建界面对象不必非得使用nib。nib加载过程中所做的事情完全可以通过代码完成。可以实例化UIView或UIView子类,配置它们,构建视图层次体系,可以将该视图层次体系添加到界面上,手工一步步完成,完全在Xcode中进行。nib只不过是一种让这个过程变得更简单、更便捷的方式而已。提前以图形化方式设计好nib;当应用运行时,代码不必实例化或配置任何视图,只需加载nib并获得生成的实例,然后将其放到界面中即可。实际上,由于你一定会用到视图控制器(UIViewController),它们本身在设计时就考虑到了nib,因此你甚至都不用使用nib!视图控制器会加载nib,获取生成的实例,并将它们放到界面上,这一切都是自动完成的。
相比于编写代码,nib是一种简单且精巧的方式,它使得设计与配置应用界面的过程变得更加简单和便捷。不过,它们可能也是iOS编程中最不易理解的方面。很多初学者从开始学习iOS第一天就知道nib,并且一直使用了很多年,但却不知道nib到底是什么,其工作原理是什么。这么做是完全错误的。nib不是魔法,理解起来并不难。重要的是,你要知道nib是什么,其工作原理是什么,如何在代码中操纵nib。没有完全理解nib会导致你陷入各种低级、混乱的问题中;而实际上,只需掌握一些基本的知识就可以完全避免或纠正这些问题。这些都是本章将要介绍的主题。
nib有必要吗?
从根本上来说,nib是实例之源,你可能想问是否可以不使用nib。这些实例也可以通过代码生成,因此完全去除nib不也可以吗?简单的答案就是:是的,没问题。我们完全可以编写一个没有.storyboard或.xib文件的复杂应用(我就这么干过)。不过,实际问题是如何做好平衡。大多数应用都至少会将nib文件作为一些界面对象之源;不过,有一些界面对象只能通过代码来定制,有时从一开始就完全通过代码来生成这些界面对象会更简单。在实际开发中,项目可能会涉及一些代码生成的界面对象与nib生成的界面对象(后者还可以通过代码做进一步的修改或是配置)。
名字nib或nib文件与钢笔或巧克力没有任何关系。Xcode提供的图形化nib设计器(称为nib编辑器)过去(一直到Xcode 3.2.x)是个单独的应用,叫作Interface Builder(Xcode中的nib编辑器环境依然被称作Interface Builder)。Interface Builder所创建的文件拥有.nib文件扩展名,这是“NeXTStep Interface Builder”的首字母缩写。时至今日,你在nib编辑器中直接编辑的文件要么是.storyboard文件,要么是.xib文件;在构建应用时,这些文件会被编译到nib文件中(参见第6章)。