Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

In a Master-Detail app I'd like to display a TableView with 5 sections titled:

  1. Your Move
  2. Their Move
  3. Won Games
  4. Lost Games
  5. Options

So I create a blank Master-Detail app in Xcode 5.0.2 and then in its MasterViewController.m (which is a UITableViewController) I'm trying to implement the method:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    return _titles[section];
}

My question is however how to init the NSArray _titles?

I'm trying in the MasterViewController.m:

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

static NSArray *_titles_1 = @[
    @"Your Move",
    @"Their Move",
    @"Won Games",
    @"Lost Games",
    @"Options"
];

@interface MasterViewController () {
    NSMutableArray *_games;

    NSArray *_titles_2 = @[
                         @"Your Move",
                         @"Their Move",
                         @"Won Games",
                         @"Lost Games",
                         @"Options"
    ];
}
@end

@implementation MasterViewController

- (void)awakeFromNib
{
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        self.clearsSelectionOnViewWillAppear = NO;
        self.preferredContentSize = CGSizeMake(320.0, 600.0);
    }
    [super awakeFromNib];
}

- (void)viewDidLoad
{
     ....
}

but both tries above give me syntax errors:

enter image description here

UPDATE:

To my surprise there are many suggestions for this simple question, but as an iOS/Objective-C newbie I'm not sure, which solution is most appropriate.

dispatch_once - isn't it a runtime operation to execute something once in a multi-threaded app? Isn't it overkill here? I was expecting a compile-time solution for initiating a const array...

viewDidLoad - when my app changes between background and foreground, wouldn't it unnecessary initiate my const array again and again?

Shouldn't I better set the NSArray in awakeFromNib (since I use stroyboard scenes for all my ViewControllers)? Or maybe in initSomething (is the correct method initWithStyle?)

like image 552
Alexander Farber Avatar asked Dec 12 '13 13:12

Alexander Farber


People also ask

How do you declare NSArray in Objective C?

In Objective-C, the compiler generates code that makes an underlying call to the init(objects:count:) method. id objects[] = { someObject, @"Hello, World!", @42 }; NSUInteger count = sizeof(objects) / sizeof(id); NSArray *array = [NSArray arrayWithObjects:objects count:count];

What is NSArray?

NSArray is an immutable Objective C class, therefore it is a reference type in Swift and it is bridged to Array<AnyObject> . NSMutableArray is the mutable subclass of NSArray .


Video Answer


4 Answers

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];
like image 134
jlehr Avatar answered Oct 20 '22 04:10

jlehr


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
like image 43
Emmanuel Avatar answered Oct 20 '22 05:10

Emmanuel


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" ]];
    }
}
like image 8
Anoop Vaidya Avatar answered Oct 20 '22 03:10

Anoop Vaidya


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]

like image 7
Pablo A. Avatar answered Oct 20 '22 05:10

Pablo A.