首页 » iOS编程基础:Swift、Xcode和Cocoa入门指南 » iOS编程基础:Swift、Xcode和Cocoa入门指南全文在线阅读

《iOS编程基础:Swift、Xcode和Cocoa入门指南》12.9 nib加载与内存管理

关灯直达底部

当nib加载时,它会实例化其nib对象(参见第7章)。这些实例化后的对象会发生什么呢?视图会保持其子视图,但顶层对象呢,它们不是任何视图的子视图。答案就是它们不会增加保持计数;如果没有其他对象保持它们,它们就会销毁。

如果不希望这种情况发生(否则为何一开始要加载这个nib呢),那就需要捕获到从nib中实例化的顶层对象的引用。可以通过两种方式做到这一点。在通过调用NSBundle的loadNibNamed:owner:options:或UINib的instantiateWithOwner:options:加载nib时会返回一个NSArray,其中包含了nib加载机制所实例化的顶层对象。因此,保持这个NSArray或其中的对象即可。

在某些情况下,你可能根本就意识不到发生了这种情况。比如,当一个视图控制器自动从故事板中实例化时,它实际上会从nib中加载,并且只有一个顶层对象,即视图控制器本身。因此,该视图控制器就是instantiateWithOwner:options:所返回的数组中的唯一一个元素。接下来,视图控制器会被从该数组中提取出来,并由运行时保持,这是通过将其添加到视图控制器层次体系中做到的。

另一种可能是通过插座变量来配置nib所有者,该插座变量会在nib顶层对象实例化时保持它们。第7章曾这么做过,那时创建了一个如下所示的插座变量:


class ViewController: UIViewController {    @IBOutlet var coolview : UIView!  

接下来手工加载nib,并将该视图控制器作为所有者:


NSBundle.mainBundle.loadNibNamed("View", owner: self, options: nil)self.view.addSubview(self.coolview)  

第一行从nib中实例化了顶层视图,nib加载机制会将其赋给self.coolview。由于self.coolview是个强引用,它会保持视图。这样,第2行将视图插入界面中时,它会还存在。

当视图控制器加载包含了主视图的nib时也会出现相同的情况。视图控制器有一个view插座变量,并且是nib的所有者。这样,视图会由nib加载机制实例化并赋给视图控制器的view属性,该属性会保持它。

不过,对于声明的@IBOutlet属性,你常常会将其标记为weak。这并不是必需的,省略weak标记也不会出现什么问题。将这种插座变量标记为weak也可以正常使用,原因在于你知道该插座变量所指向的对象还会由其他对象保持,比如,它是视图控制器主视图的一个子视图。视图会由其父视图保持,这样除非后面将其从父视图中移除,否则你知道它会一直存在,@IBOutlet属性没必要再保持它了。