【问题标题】:Multiple storyboards: should I use a singleton pattern to cache them?多个故事板:我应该使用单例模式来缓存它们吗?
【发布时间】:2015-06-23 23:43:53
【问题描述】:

我在我的应用中使用了多个故事板,这被认为是一种很好的做法。例如,在Main.storyboard 中的FooViewController 中,当点击按钮时,我会以编程方式跳转到Secondary.storyboard 中定义的另一个BarViewController

情节提要和视图控制器之间的转换在单独的文件中实现,例如Storyboards,如下:

// in Storyboards.m
@implementation Storyboards

+ (id)instantiateBarViewController {
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Secondary" bundle:nil];
    return [storyboard instantiateViewControllerWithIdentifier:@"BarViewController"];
}

@end

然后在FooViewController,我这样做了:

// in FooViewController.m
- (IBAction)someButtonTapped:(id)sender {
    BarViewController *controller = [Storyboards instantiateBarViewController];
    [self.navigationController pushViewController:controller animated:YES];
}

这很好用。但我的问题是:

  1. 是否需要缓存storyboard实例,这样每次调用instantiateBarViewController就不需要重新创建storyboard?
  2. 如果是,我是否也应该缓存BarViewController

要缓存故事板(和视图控制器),我可以使用如下代码:

// in Storyboards.m
@implementation Storyboards

+ (id)instantiateBarViewController {
    static UIViewController *barViewController = nil;  // Shared view controller.
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        UIStoryboard *storyboard = [self secondaryStoryboard];
        barViewController = [storyboard instantiateViewControllerWithIdentifier:@"BarViewController"];
    });
    return barViewController;
}

+ (UIStoryboard *)secondaryStoryboard {
    static UIStoryboard *storyboard = nil;  // Shared storyboard.
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        storyboard = [UIStoryboard storyboardWithName:@"Secondary" bundle:nil];
    });
    return storyboard;
}

@end

谢谢!

【问题讨论】:

  • 这对我来说似乎是过早优化的情况。
  • 我会采用不同的方法并使用:github.com/rob-brown/RBStoryboardLink 它允许您直观地链接故事板。非常强大的工具
  • @AshleyMills 我对此也有疑问,这就是为什么我在我的应用程序中实现它之前在 SO 中提出这个问题的原因。 ;-)
  • @SimonMcLoughlin 感谢您的链接。我也知道这个项目,但我更喜欢使用手动方式来做到这一点。因为:1)我认为代码会更容易理解; 2) 正如该项目所述:“RBStoryboardLink 最初是作为概念验证的,现在基本上仍然如此。” -- 但如果您认为我的手动方法与 RBStoryboardLink 相比存在严重缺陷或明显劣势,我很高兴知道并切换到 RBStoryboardLink。

标签: ios objective-c cocoa-touch storyboard


【解决方案1】:

我会说“不要”。

像这样保留对资源的引用意味着您将内容塞入内存受限设备的内存中,并且永远不会放开它们。 糟糕的开发者!没有 cookie! ;-)

您有什么证据表明这比让系统管理缓存或从 xibs 重复加载的资源(确实如此)更好?我想说你的方法可能弊大于利。请记住,简单地创建一个故事板实例并不直接转化为“每次都从文件系统加载它”。系统对此进行了相当智能的管理,因此无需通过维护从未释放的引用来将其短路。

如果您想解决一些性能问题,我强烈建议您使用 Instruments 来衡量性能并从那里着手。我严重怀疑这是故事板/xib 加载问题。

【讨论】:

    【解决方案2】:

    单例似乎有点矫枉过正——从情节提要中实例化视图控制器所需要做的就是:

    [[UIStoryboard storyboardWithName: @"<storyboard-name>" bundle: nil] instantiateViewControllerWithIdentifier: @"<identifier>"];

    [[UIStoryboard storyboardWithName: @"<storyboard-name>" bundle: nil] instantiateInitialViewController];

    [self.storyboard instantiateViewControllerWithIdentifier: @"<identifier>"];

    保持简单!

    【讨论】:

    • 感谢您的回答!我赞成它,但我会接受第一个答案,这与你的观点几乎相同。 :-)
    • 接受回答者的另一个赞成票。我发布了我的,因为我觉得有必要详细说明。我很啰嗦。 ;-)
    猜你喜欢
    • 2010-12-01
    • 2017-03-10
    • 2016-08-15
    • 2013-10-29
    • 2023-04-04
    • 1970-01-01
    • 2019-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多