Multiple storyboards: should I use a singleton pattern to cache them?

别来无恙 提交于 2020-01-04 15:57:35

问题


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.

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

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

Thanks!


回答1:


I'd say "don't."

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! ;-)

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.

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.




回答2:


A singleton seems overkill - all you need to instantiate a view controller from a storyboard is:

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

or

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

or

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

Keep it simple!



来源:https://stackoverflow.com/questions/29693848/multiple-storyboards-should-i-use-a-singleton-pattern-to-cache-them

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!