Как объявить массив как константу в Objective-c?
Следующий код дает мне ошибки:
// constants.h
extern NSArray const *testArray;
// constants.m
NSArray const *testArray = [NSArray arrayWithObjects: @"foo", @"bar", nil];
Ошибка, которую я получаю, - это
initializer element is not constant
Или, если я заберу указатель указателя (*), я получу:
statically allocated instance of Objective-C class 'NSArray'
Ответы
Ответ 1
Короче говоря, вы не можете. Objective-C объекты, за исключением констант NSString, создаются только во время выполнения и, следовательно, вы не можете использовать выражение для их инициализации.
Существует несколько подходов.
(1) Объявите NSArray *testArray
без ключевого слова const
, а затем немного кода, который устанавливает значение, которое вызывается очень рано в течение жизненного цикла приложения.
(2) Объявите удобный метод класса, который возвращает массив, затем используйте static NSArray *myArray
внутри этого метода и рассмотрите его как одноэлементный (поиск SO для "objective-c singleton" примерно за два миллиона ответов о том, как создать экземпляр).
Ответ 2
Немного поздно для вечеринки, но поскольку вы не меняете значения по ходу программы, если вы имеете дело со строками, вы можете сделать следующее, объявив свой массив с помощью массива C
:
extern NSString * const MY_CONSTANT_STRING_ARRAY[];
в вашем файле constants.h
, а затем в constants.m
вы можете добавлять к нему объекты следующим образом:
NSString * const MY_CONSTANT_STRING_ARRAY[] = { @"foo", @"bar" };
Затем, чтобы получить доступ к члену, вы можете сделать цикл for так же, как с оператором C
sizeof()
:
Это, очевидно, массив C
, а не NSArray
, поэтому вы не получите все приложенные к нему методы удовольствия, например objectAtIndex:
, поэтому вы можете создать вспомогательную функцию где-нибудь в вашей программе, которая проходит через все строки, используя описанный выше метод, и возвращает NSArray
(или NSMutableArray
четный). Но если вы делаете то, что мне нужно, и вам нужен постоянный массив значений NSString
для использования во всей вашей программе, этот метод работает наилучшим образом.
Выполнение этого способа инкапсулирует все ваши строковые массивы в constants.h
и по-прежнему доступно во всей вашей программе, добавив constants.h
в ваш файл .pch
вместо создания синглета только для этого массива значений или настройки массив с небольшим кодом, который sorta поражает цель файла constants
, поскольку он удаляет фактические константы из файла constants
..
РЕДАКТИРОВАТЬ за комментарий @JesseGumpo:
Так как могут возникнуть проблемы с использованием sizeof()
для определения размера массива, простым обходным путем является объявление размера массива в файле констант следующим образом:
//.h
extern int SIZE_OF_MY_CONSTANTS_ARRAY;
///.m
int SIZE_OF_MY_CONSTANTS_ARRAY = 2;
И затем для доступа к членам в цикле for вы можете сделать это следующим образом:
for (int i=0; i < SIZE_OF_MY_CONSTANTS_ARRAY; i++)
NSLog(@"my constant string is: %@", MY_CONSTANT_STRING_ARRAY[i]);
Да, это не динамически захватывает размер массива, но если вы объявляете массив в файле констант, вы уже знаете размер этого массива с самого начала, поэтому, хотя он добавляет еще две строки кода, он все еще выполняет задачу наличия массива в файле констант.
Если у кого-то есть дополнительные предложения или могут быть известны другие трюки C
, пожалуйста, оставьте комментарий ниже!
Ответ 3
Здесь макрос, чтобы сделать это в одной строке для статического экземпляра в области метода.
#define STATIC_ARRAY(x, ...) \
static NSArray* x=nil; \
static dispatch_once_t x##onceToken; \
dispatch_once(&x##onceToken, ^{ x = @[ __VA_ARGS__ ]; });
Пример использования
STATIC_ARRAY(foo, @"thing1", @"thing2", [NSObject new]);
Ответ 4
Это довольно легко:
#define arrayTitle [NSArray arrayWithObjects: @"hi",@"foo",nil]
поставить перед реализацией и без точки с запятой.
надеюсь, что это поможет.
Ответ 5
Для меня удобнее использовать следующую реализацию для массива констант
static NSString * kHeaderTitles [3] = {@ "ACCOUNT DETAILS", @ "SOCIAL NETWORK", @ "SETTINGS"};
static int kNumbers[3] = {1, 2, 3};
Ответ 6
У меня есть заголовочный файл под названием "Constants.h" и в следующих постоянных массивах:
#define arrayOfStrings @[@"1", @"2", @"3", @"4"]
#define arraysOfIds @[@(1), @(2), @(3), @(4)]
В основном, когда вы вызываете arrayOfStrings в вашем коде, его заменяют на @[@ "1", @ "2", @ "3", @ "4" ] и то же самое на arraysOfIds.