Static NSArray of strings - how/where to initialize in a View Controller

南楼画角 提交于 2019-11-28 16:39:21

Write a class method that returns the array.

+ (NSArray *)titles
{
    static NSArray *_titles;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _titles = @[@"Your Move",
                    @"Their Move",
                    @"Won Games",
                    @"Lost Games",
                    @"Options"];
    });
    return _titles;
}

Then you can access it wherever needed like so:

NSArray *titles = [[self class] titles];

You can init it in class method +initialize

static NSArray *_titles_1;

@implementation MasterViewController
+ (void)initialize {
    _titles_1 = @[
        @"Your Move",
        @"Their Move",
        @"Won Games",
        @"Lost Games",
        @"Options"
    ];
}
@end

You should declare your static array above @implementation.

static NSArray *titles_1 = nil;

@implementation ...

And define it in init or awakeFromNib or any other method like viewDidLoad, applicationDidFinishLaunching wherever you want.

- (void)initMethod{ //change the method name accordingly

    if (titles_1 == nil){
        [self setTitles_1:@[ @"Your Move", @"Their Move", @"Won Games", @"Lost Games", @"Options" ]];
    }
}

You can also do something like this:

static NSString * const strings[] = {
        [0] = @"string_1",
        [1] = @"string_2",
        [2] = @"string_3",
        [3] = @"string_4",
        // ...
    };

It's not an NSArray but you can access NSStrings like this strings[n]

I wonder, if the following would be a good way (answering my own question):

#import "MasterViewController.h"
#import "DetailViewController.h"

static const NSArray *_titles;

@interface MasterViewController () {
    NSMutableArray *_objects;
    NSMutableArray *_yourMove;
    NSMutableArray *_theirMove;
    NSMutableArray *_wonGames;
    NSMutableArray *_lostGames;
    NSMutableArray *_options;
}
@end

@implementation MasterViewController

+ (void)initialize
{
    // do not run for derived classes
    if (self != [MasterViewController class])
        return;

    _titles = @[
        @"Your Move",
        @"Their Move",
        @"Won Games",
        @"Lost Games",
        @"Options"
    ];
}

This way the const NSArray is initalized once and right before I need it (in the MasterViewController class). And the self check prevents this method from running again - when some inheriting class does not implement its own +initialize method.

You can't instantiate objects in this way, you can only declare them in interfaces. Do the following:

static NSArray *_titles_2;

@interface MasterViewController () {
    NSMutableArray *_games;
}
@end

@implementation MasterViewController
-(void)viewDidLoad()
{
     _titles_2 = @[
                         @"Your Move",
                         @"Their Move",
                         @"Won Games",
                         @"Lost Games",
                         @"Options"
    ];
}
@end
  • or likewise you could use the viewcontroller init method instead of viewDidLoad

dispatch_once works. It works in complicated cases, and it works in simple cases. So to be consistent, the best thing is to use it in all cases. That makes it for example a lot easier when you replace all your constant strings with calls to NSLocalizedString (). No code change needed.

Doing things in + (void)initialize isn't really wrong, but I have had situations where I first wanted to configure a class before really using it, and initialize is of course called just before any possible configuration method would start executing. And there are situations where you don't really have a class context. dispatch_once will always work.

I prefer to use Objective-C++,change filename from xxx.m to xxx.mm,and the initialize of NSArray will happen at runtime

no dispatch_once,no class method,just write it in one line:

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