在故事板中加载 nib 时 IBOutlet 为 nil

栏目: IOS · 发布时间: 7年前

内容简介:故事板是在 iOS 5 开始出现的,在此之前我们使用的是 nib/xib。一个故事板支持多个 ViewController,同时可以在这些 ViewController 中进行连接(segue)。但是随着工程中 ViewController 的增加,故事板中 ViewController 之间的连线变得纷乱复杂,故事板也就失去了原来的意义。与之相比较,nib/xib 只支持单一的 ViewController,这种因为简单带来的清晰使得它在项目中仍然被大量使用。但是,如果在项目中混合使用故事板和 nib

故事板是在 iOS 5 开始出现的,在此之前我们使用的是 nib/xib。一个故事板支持多个 ViewController,同时可以在这些 ViewController 中进行连接(segue)。但是随着工程中 ViewController 的增加,故事板中 ViewController 之间的连线变得纷乱复杂,故事板也就失去了原来的意义。与之相比较,nib/xib 只支持单一的 ViewController,这种因为简单带来的清晰使得它在项目中仍然被大量使用。

但是,如果在项目中混合使用故事板和 nib 文件,可能会带来一些意想不到的问题。一个典型的问题是,storyboard 加载 nib 中的 view controller 时,这个 view controller 中的 IBOutlet 都会丢失连接,这样在 viewDidLoad 后,所有的 IBOutlet 属性都为 nil,你根本无法使用这些属性。你可以来看一个例子。

  1. 新建一个 Single View 项目。

  2. 新建一个 UIViewController 子类,名字叫做 TestViewController,确认勾上 Also create xib file。

  3. 打开 TestViewController.xib 文件,拖入一个 label,为这个按钮建立一个到 IBOutlet 属性 label 的连接。

  4. 在 TestViewController.m 的 viewDidLoad 方法中,加入这句:

    _label.text = @"我是一个 Label";

    同时在这句上打一个断点。

  5. 打开 Main.storyboard。在 ViewController 上放一个按钮。title 设置为“下一步”。

  6. 拖入一个 UIViewController。 将 Class 改成 TestViewController。

  7. 使用 Embed in Navigation Contorller,将 View Controller 外面套上一个导航控制器。

  8. 在 View Controller 和 TestViewController 之间添加一个 segue,ID 不妨叫做 test。

    在故事板中加载 nib 时 IBOutlet 为 nil
  9. 为 View Controller 上的“下一步”按钮创建一个 IBAction buttonClicked,在里面编写代码:

    -(void)buttonClicked{
    [self performSegueWithIdentifier:@"test" sender:nil];

这样,当按钮一点击,导航控制器会跳到 TestViewController。

Build & run,点击“下一步”按钮,断点停下,将鼠标放在 _label 变量上查看值,发现值为 nil,继续执行,Label 上的文字不会改变。

这个问题说明,故事板在加载 nib 文件时,不会自动加载 nib 文件中的内容。为了搞清楚故事板是如何加载 TestViewController 类的,我们在 TestViewController.m 中增加两个初始化方法,并在每个方法中打上断点:

-(instancetype)initWithCoder:(NSCoder *)aDecoder{
    self = [super initWithCoder:aDecoder];
    
    return self;
}
-(instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
    return [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
}

Build & run,我们发现断点在 initWithCoder: 方法中停下。说明故事板是调用这个方法来初始化 TestViewController 的。

我们将这个方法修改为:

-(instancetype)initWithCoder:(NSCoder *)aDecoder{
    self = [super initWithNibName:NSStringFromClass([self class]) bundle:nil];
    
    return self;
}

这样,故事板就会从 nib 文件中加载 TestViewController 了。Build & run,当断点停下,观察 _label 变量,现在它不再为 nil 了:

在故事板中加载 nib 时 IBOutlet 为 nil

继续执行,TestViewController 上 Label 的文字成功被我们改变成“我是一个 Label”。

当然,我们也可以用代码创建 TestViewController, 而不是让故事板为我们创建 TestViewController。

在 Main.storyboard 中删除 Test View Controller,然后修改 View Controller 的 buttonClicked 方法:

TestViewController* vc = [TestViewController new];

    [self.navigationController pushViewController:vc animated:YES];

效果也是一样的。


以上所述就是小编给大家介绍的《在故事板中加载 nib 时 IBOutlet 为 nil》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

社群运营五十讲

社群运营五十讲

陈菜根 / 北京时代华文书局 / 2018-4-1 / 49.80

物以类聚,人以群分,社群营销不只是简单的建群、卖东西,而是建立一种自动运转的,去中心化的生态圈,让相同爱好的人产生关系,迸发出裂变的火花,创造更多的营销机会。本书从基本的社群概念入手,讲解了社群的五大要素,社群活动的运作,社群的变现模式以及如何做一个社群师等内容,最后再从如何打造社群IP入手,详细讲解了社群IP的定义、分类及操作过程。一起来看看 《社群运营五十讲》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

html转js在线工具
html转js在线工具

html转js在线工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具