多个情节提要:我应该使用单例模式来缓存它们吗?

问题描述:

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

I'm using multiple storyboards in my app, which is considered as good practice. For example, from my FooViewController in Main.storyboard, when a button is tapped, I'll jump to another BarViewController defined in Secondary.storyboard programmatically.

故事板和视图控制器在单独的文件中实现,例如 Storyboards ,如下所示:

Transitions among storyboards and view controllers are implemented in a separate file, e.g. Storyboards, like the following:

// in Storyboards.m
@implementation Storyboards

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

@end

然后在 FooViewController ,我是这样做的:

Then in FooViewController, I did this:

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

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

This works just fine. But my questions are:


  1. 是否有必要缓存情节提要实例,以便每次 instantiateBarViewController 被调用,我不需要重新创建情节提要吗?

  2. 如果是,我也应该缓存 BarViewController 吗?

  1. Is it necessary to cache the storyboard instance, so that everytime instantiateBarViewController is invoked, I do not need to re-create the storyboard?
  2. If yes, should I cache BarViewController too?

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

To cache the storyboard (and the view controller), I could use code as the following:

// 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

谢谢!

我会说不要。

保持对这样的资源的引用意味着您将东西塞进内存受限的设备中,而永远不会放过它们。 糟糕的开发者!没有cookie! ;-)

Keeping references to resources like this means you're stuffing things into memory on a memory-restricted device and never, ever letting them go. Bad developer! No cookie! ;-)

您有什么证据表明这比让系统管理从xibs重复加载的资源缓存或垃圾回收更好(它是做什么的?我想说您的方法弊大于利。请记住,仅创建一个故事板实例并不能直接转化为每次都从文件系统中加载它。系统相当智能地管理它,因此不需要通过维护永远不会发布的引用来使其短路。

What evidence do you have that would suggest this is better than letting the system manage caching or trashing resources repeatedly loaded from xibs (which it does)? I'd say your approach is likely doing more harm than good. Remember, simply creating a storyboard instance doesn't directly translate to "loading it from the file system every time". The system manages this rather intelligently, so there's no need to short-circuit it by maintaining references that are never released.

如果您要解决一些性能问题,我强烈建议您使用Instruments来衡量性能并从那里开始。我严重怀疑这是情节提要/ xib加载问题。

If you're trying to solve some performance problem, I highly recommend using Instruments to measure performance and go from there. I seriously doubt it's a storyboard/xib loading issue.