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

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

内容简介:故事板是在 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》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

运营前线 2

运营前线 2

兰军 等著 / 机械工业出版社 / 2017-4 / 69.00

“运营前线”是一个系列,目前已经出版2部,与“产品前线”一样,该系列书也由资深的产品和运营专家兰军(Blues)领衔策划和写作,旨在梳理和总结国内一线互联网公司的运营方法和技巧,让所有产品人和运营人都有机会了解和学习这些大的互联网公司是如何做运营的。 这2部作品汇集了来自腾讯、阿里、百度、360、迅雷、YY、小米、爱奇艺、乐视等数十家大型互联网公司的一线运营专家的技巧和方法论。共包含9大运营......一起来看看 《运营前线 2》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具