Как я могу использовать NSArray в качестве глобальной константы?

Я использую ряд Constant.m файлы, один на цель, для определения определенных вещей для каждой цели. Например:

// Constants.h
extern NSString * const kDatabaseFileName;
//Constants.m
NSString * const kDatabaseFileName = @"target_one.sqlite";

Я также хотел бы определить NSArray для каждой из моих целей:

NSArray * const kLabelNames = [[NSArray alloc] initWithObjects:
    @"nameLabel", @"addressLabel", nil];

Но это дает "ошибку: элемент инициализатора не является постоянным". Используя 'arrayWithObjects' не работает также. Это вызвано тем, что строки в моем массиве не являются константами?

Как я могу настроить массив как глобальную константу?Спасибо.

11
задан nevan king 22 July 2010 в 19:22
поделиться

3 ответа

Если вам нужен набор констант, включающий типы NS, рассмотрите возможность размещения их всех в синглтоне.

У вас может быть один файл заголовка и несколько файлов реализации (по одному для каждой цели). Если все это реализует класс, объявленный в файле заголовка, все будет в порядке.

6
ответ дан 3 December 2019 в 01:02
поделиться

В Objective-C объекты можно размещать только в куче, поэтому нет способа создать массив NSArray в статической памяти. Однако вы можете создать массив C указателей на константы NSString, например, так ...

NSString * const kLabelNames[] = {
    @"Foo", @"Bar", @"Baz"
};

... а затем вы можете написать методы класса, подобные этому ...

+ (NSArray *)labelNames
{
    static NSArray *names;
    if (names == nil) {
        names = [[NSArray alloc] initWithObjects:kLabelNames count:3];
    }
    return names;
}

Edit

Обратите внимание, что с введением новые технологии, такие как ARC, Grand Central Dispatch и новый буквальный синтаксис для массивов, теперь есть более простой способ выполнить нечто подобное. Обратите внимание, что приведенный ниже пример также обеспечивает большую безопасность потоков, хотя исходный пример мог бы включать блок @synchronized или один из нескольких других механизмов для достижения аналогичных результатов.

+ (NSArray *)labelNames
{
    static NSArray *names;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        names = @[@"Foo", @"Bar", @"Baz"];
    });

    return names;
}

Однако приведенный выше пример не полностью отвечает на исходный вопрос. Если глобальный массив констант действительно необходим, предыдущий пример можно было бы переписать в том же духе, что и исходный ответ, при этом используя преимущества GCD:

NSString * const kLabelNames[] = {
    @"Foo", @"Bar", @"Baz"
};

+ (NSArray *)labelNames
{
    static NSArray *names;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        names = [NSArray arrayWithObjects:kLabelNames count:3];
    });

    return names;
}
28
ответ дан 3 December 2019 в 01:02
поделиться

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

Если вы используете его часто, вы можете создать протокол, определяющий имена методов. Затем замените класс, реализующий протокол в каждой цели, чтобы один и тот же код при необходимости возвращал разные значения.

2
ответ дан 3 December 2019 в 01:02
поделиться