在故事板中加载 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-9 / 65.00元

小米新零售,如何做到20倍坪效? 天猫小店,如何利用大数据助力线下零售? 盒马鲜生,为什么坚持必须用App才能买单? 名创优品,实体小店在电商冲击下,如何拥抱春天? 新零售的未来在何方?什么样的思维模式才可应对? 新零售,不是商界大佬的专用名词,它就在我们生活触手可及的各个角落——小到便利店的酸奶,大到京东商城的冰箱,都蕴含着消费者、货物、经营场所三者共同作用的经济逻......一起来看看 《新零售:低价高效的数据赋能之路》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

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

RGB CMYK 互转工具