Подтвердить что ты не робот

Статический NSArray строк - как/где инициализировать в контроллере просмотра

В приложении "Мастер-детали" я хочу отобразить TableView с 5 разделами под названием:

  • Ваше движение
  • Их движение
  • Выиграть игры
  • Потерянные игры
  • Параметры

Итак, я создаю пустое приложение Master-Detail в Xcode 5.0.2, а затем в его MasterViewController.m(которое является UITableViewController) Я пытаюсь реализовать метод:

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

Мой вопрос - как инициализировать NSArray _titles?

Я пытаюсь в 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
{
     ....
}

но оба примера выше дают мне синтаксические ошибки:

enter image description here

UPDATE:

К моему удивлению, есть много предложений по этому простому вопросу, но как новичок iOS/ Objective-C я не уверен, какое решение является наиболее подходящим.

dispatch_once - разве это не операция выполнения для выполнения чего-то один раз в многопоточном приложении? Разве это не слишком много? Я ожидал решения для компиляции времени для инициализации массива const...

viewDidLoad - когда мое приложение меняется между фоном и передним планом, не будет ли лишним инициировать мой массив const снова и снова?

Не следует ли лучше установить NSArray в awakeFromNib (так как я использую сценарии стройструктуры для всех моих ViewControllers)? Или, может быть, в initSomething (правильный метод initWithStyle?)

4b9b3361

Ответ 1

Напишите метод класса, который возвращает массив.

+ (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;
}

Затем вы можете получить доступ к нему везде, где это необходимо:

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

Ответ 2

Вы можете запустить его в методе класса + initialize

static NSArray *_titles_1;

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

Ответ 3

Вы должны объявить свой статический массив выше @implementation.

static NSArray *titles_1 = nil;

@implementation ...

И определите его в init или awakeFromNib или любом другом методе, например viewDidLoad, applicationDidFinishLaunching, где хотите.

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

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

Ответ 4

Вы также можете сделать что-то вроде этого:

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

Это не NSArray, но вы можете получить доступ к NSStrings следующим образом: strings[n]

Ответ 5

Интересно, если бы следующее было хорошим способом (отвечая на мой собственный вопрос):

#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"
    ];
}

Таким образом, const NSArray инициализируется один раз и прямо перед тем, как он мне понадобится (в классе MasterViewController). И проверка self запрещает запуск этого метода снова - когда некоторый класс наследования не реализует свой собственный метод +initialize.

Ответ 6

Вы не можете создавать объекты таким образом, вы можете объявлять их только в интерфейсах. Выполните следующие действия:

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
  • или аналогичным образом вы можете использовать метод init viewcontroller вместо viewDidLoad

Ответ 7

dispatch_once работает. Он работает в сложных случаях, и он работает в простых случаях. Чтобы быть последовательным, лучше всего использовать его во всех случаях. Это делает его, например, намного проще, когда вы заменяете все свои постоянные строки вызовами NSLocalizedString(). Никакого изменения кода не требуется.

Выполнение вещей в инициализации + (void) на самом деле не так, но у меня были ситуации, когда я сначала хотел сконфигурировать класс, прежде чем использовать его, и инициализация, конечно, называется непосредственно перед началом любого возможного способа настройки, И бывают ситуации, когда у вас действительно нет контекста класса. dispatch_once всегда будет работать.

Ответ 8

Я предпочитаю использовать Objective-C ++, изменить имя файла от xxx.m до xxx.mm, а инициализация NSArray произойдет во время выполнения

no dispatch_once, нет, просто напишите его в одной строке:

static NSArray *const a = @[@"a",@"b",@"c"];