如何在Objective-c中将数组声明为常量?

时间:2021-02-26 20:57:15

The following code is giving me errors:

下面的代码给了我错误:

//  constants.h
extern NSArray const *testArray;
//  constants.m
NSArray const *testArray = [NSArray arrayWithObjects:  @"foo", @"bar", nil];

The error I get is
initializer element is not constant

我得到的错误是初始化元素不是常量

Or if I take away the pointer indicator (*) I get:
statically allocated instance of Objective-C class 'NSArray'

或者如果我去掉指针指示器(*)我得到:Objective-C类'NSArray'的静态分配实例

6 个解决方案

#1


67  

In short, you can't. Objective-C objects are, with the exception of NSString constants, only ever created at runtime and, thus, you can't use an expression to initialize them.

简而言之,你不能。除NSString常量外,Objective-C对象只在运行时创建,因此不能使用表达式初始化它们。

There are a handful of approaches.

有几种方法。

(1) Declare NSArray *testArray without the const keyword and then have a bit of code that sets up the value that is invoked very early during application lifecycle.

(1)在没有const关键字的情况下声明NSArray *testArray,然后有一些代码来设置在应用程序生命周期早期被调用的值。

(2) Declare a convenient class method that returns the array, then use a static NSArray *myArray within that method and treat it as a singleton (search SO for "objective-c singleton" for about a zillion answers on how to instantiate).

(2)声明一个返回数组的方便的类方法,然后在该方法中使用静态的NSArray *myArray,并将其视为一个单例(搜索“objective-c singleton”,以获得关于如何实例化的无数答案)。

#2


31  

A little late to the party, but since you're not changing the values through the course of the program, if you were only dealing with strings, you could do the following by declaring your array using a C array:

有点晚了,但是由于在整个程序过程中没有改变值,如果只处理字符串,可以使用C数组声明数组:

extern NSString * const MY_CONSTANT_STRING_ARRAY[];

in your constants.h file, and then in your constants.m you could add objects to it like so:

在你的常量。h文件,然后在常数中。m你可以像这样添加对象:

NSString * const MY_CONSTANT_STRING_ARRAY[] = { @"foo", @"bar" };

Then to access a member, you could do a for loop like so with a C sizeof() operator:

然后,要访问一个成员,您可以使用C sizeof()操作符执行一个for循环:

This obviously is a C array and not a NSArray so you don't get all of the fun methods attached to it like objectAtIndex:, so you could create a helper function somewhere in your program that loops through all of the strings using the method I outlined above and returns an NSArray (or NSMutableArray even). But, if you were doing what I am and just need a constant array of NSString values to use throughout your program, this method works the best.

这显然是一个C数组而不是NSArray所以你不要让所有的有趣的方法附加到它,objectAtIndex:,所以你可以创建一个helper函数在程序循环通过使用上述方法我所有的字符串并返回NSArray(甚至NSMutableArray)。但是,如果您正在做我所做的事情,并且只需要在整个程序中使用一个常量NSString值数组,那么这个方法效果最好。

Doing it this way encapsulates all of your string array contants in constants.h, and is still available throughout your program by adding constants.h in your .pch file instead of creating a singleton just for this array of values or setting the array with a little code, which sorta defeats the purpose of a constants file because it removes the actual constants out of the constants file..

这样做可以将所有字符串数组内容都封装在常量中。h,通过添加常量仍然可以在整个程序中使用。h在你的。pch文件中,而不是为这个值数组创建一个单例,或者用一个小代码设置数组,这破坏了常量文件的目的,因为它从常量文件中删除了实际的常量。

EDIT per @JesseGumpo's Comment:

编辑/ @JesseGumpo的评论:

Since there may be issues with using sizeof() to determine the size of the array, a simple workaround is to declare the size of the array in your constants file like so:

由于使用sizeof()来确定数组的大小可能存在问题,一个简单的解决方案是在常量文件中声明数组的大小,如下所示:

//.h
extern int SIZE_OF_MY_CONSTANTS_ARRAY;  

///.m
int SIZE_OF_MY_CONSTANTS_ARRAY = 2;

And then to access the members in a for loop you can do so like this:

然后要访问for循环中的成员,你可以这样做:

for (int i=0; i < SIZE_OF_MY_CONSTANTS_ARRAY; i++) 
        NSLog(@"my constant string is: %@", MY_CONSTANT_STRING_ARRAY[i]);

Yes, this doesn't dynamically capture the size of the array, but if you're declaring an array in a constants file you already know the size of that array from the start, so even though it adds two more lines of code, it still accomplishes the task of having an array in a constants file.

是的,这不是动态捕捉数组的大小,但是如果你声明一个数组常量文件你已经知道这个数组的大小从一开始,所以即使它添加两行代码,它仍然完成的任务在一个数组常量文件。

If anyone has any more suggestions or may know some other C tricks please leave a comment below!

如果有人有任何建议或可能知道其他一些C技巧,请在下面留言!

#3


9  

Here's a macro to do it in one line for a static instance in a method scope.

这里有一个宏,用于在方法作用域中的静态实例的一行中执行此操作。

#define STATIC_ARRAY(x, ...)   \
        static NSArray* x=nil; \
        static dispatch_once_t x##onceToken; \
        dispatch_once(&x##onceToken, ^{ x = @[ __VA_ARGS__ ]; });

Use example

使用的例子

    STATIC_ARRAY(foo, @"thing1", @"thing2", [NSObject new]);

#4


6  

It's pretty easy :

它很简单:

#define arrayTitle [NSArray arrayWithObjects: @"hi",@"foo",nil]

定义arrayTitle [NSArray arrayWithObjects: @"hi",@"foo",nil]

put before implementation and without semicolon.

在实现之前,不要使用分号。

hope it helps.

希望它可以帮助。

#5


3  

As for me, it is more convenient to use the following implementation for an array of constants

对于我来说,对一个常量数组使用以下实现更方便

static NSString * kHeaderTitles [3] = {@ "ACCOUNT DETAILS", @ "SOCIAL NETWORK", @ "SETTINGS"};
static int kNumbers[3] = {1, 2, 3};

#6


3  

I have a header file called "Constants.h" and within the next constant arrays:

我有一个头文件叫做“常量”。h”和在下一个常量数组中:

#define arrayOfStrings @[@"1", @"2", @"3", @"4"]
#define arraysOfIds @[@(1), @(2), @(3), @(4)]

Basically, when you call arrayOfStrings in your code, is replaced with @[@"1", @"2", @"3", @"4"] and the same thing with arraysOfIds.

基本上,当您在代码中调用arrayofstring时,会被替换为@[@"1",@"2",@"3",@"4"],arraysOfIds也是如此。

#1


67  

In short, you can't. Objective-C objects are, with the exception of NSString constants, only ever created at runtime and, thus, you can't use an expression to initialize them.

简而言之,你不能。除NSString常量外,Objective-C对象只在运行时创建,因此不能使用表达式初始化它们。

There are a handful of approaches.

有几种方法。

(1) Declare NSArray *testArray without the const keyword and then have a bit of code that sets up the value that is invoked very early during application lifecycle.

(1)在没有const关键字的情况下声明NSArray *testArray,然后有一些代码来设置在应用程序生命周期早期被调用的值。

(2) Declare a convenient class method that returns the array, then use a static NSArray *myArray within that method and treat it as a singleton (search SO for "objective-c singleton" for about a zillion answers on how to instantiate).

(2)声明一个返回数组的方便的类方法,然后在该方法中使用静态的NSArray *myArray,并将其视为一个单例(搜索“objective-c singleton”,以获得关于如何实例化的无数答案)。

#2


31  

A little late to the party, but since you're not changing the values through the course of the program, if you were only dealing with strings, you could do the following by declaring your array using a C array:

有点晚了,但是由于在整个程序过程中没有改变值,如果只处理字符串,可以使用C数组声明数组:

extern NSString * const MY_CONSTANT_STRING_ARRAY[];

in your constants.h file, and then in your constants.m you could add objects to it like so:

在你的常量。h文件,然后在常数中。m你可以像这样添加对象:

NSString * const MY_CONSTANT_STRING_ARRAY[] = { @"foo", @"bar" };

Then to access a member, you could do a for loop like so with a C sizeof() operator:

然后,要访问一个成员,您可以使用C sizeof()操作符执行一个for循环:

This obviously is a C array and not a NSArray so you don't get all of the fun methods attached to it like objectAtIndex:, so you could create a helper function somewhere in your program that loops through all of the strings using the method I outlined above and returns an NSArray (or NSMutableArray even). But, if you were doing what I am and just need a constant array of NSString values to use throughout your program, this method works the best.

这显然是一个C数组而不是NSArray所以你不要让所有的有趣的方法附加到它,objectAtIndex:,所以你可以创建一个helper函数在程序循环通过使用上述方法我所有的字符串并返回NSArray(甚至NSMutableArray)。但是,如果您正在做我所做的事情,并且只需要在整个程序中使用一个常量NSString值数组,那么这个方法效果最好。

Doing it this way encapsulates all of your string array contants in constants.h, and is still available throughout your program by adding constants.h in your .pch file instead of creating a singleton just for this array of values or setting the array with a little code, which sorta defeats the purpose of a constants file because it removes the actual constants out of the constants file..

这样做可以将所有字符串数组内容都封装在常量中。h,通过添加常量仍然可以在整个程序中使用。h在你的。pch文件中,而不是为这个值数组创建一个单例,或者用一个小代码设置数组,这破坏了常量文件的目的,因为它从常量文件中删除了实际的常量。

EDIT per @JesseGumpo's Comment:

编辑/ @JesseGumpo的评论:

Since there may be issues with using sizeof() to determine the size of the array, a simple workaround is to declare the size of the array in your constants file like so:

由于使用sizeof()来确定数组的大小可能存在问题,一个简单的解决方案是在常量文件中声明数组的大小,如下所示:

//.h
extern int SIZE_OF_MY_CONSTANTS_ARRAY;  

///.m
int SIZE_OF_MY_CONSTANTS_ARRAY = 2;

And then to access the members in a for loop you can do so like this:

然后要访问for循环中的成员,你可以这样做:

for (int i=0; i < SIZE_OF_MY_CONSTANTS_ARRAY; i++) 
        NSLog(@"my constant string is: %@", MY_CONSTANT_STRING_ARRAY[i]);

Yes, this doesn't dynamically capture the size of the array, but if you're declaring an array in a constants file you already know the size of that array from the start, so even though it adds two more lines of code, it still accomplishes the task of having an array in a constants file.

是的,这不是动态捕捉数组的大小,但是如果你声明一个数组常量文件你已经知道这个数组的大小从一开始,所以即使它添加两行代码,它仍然完成的任务在一个数组常量文件。

If anyone has any more suggestions or may know some other C tricks please leave a comment below!

如果有人有任何建议或可能知道其他一些C技巧,请在下面留言!

#3


9  

Here's a macro to do it in one line for a static instance in a method scope.

这里有一个宏,用于在方法作用域中的静态实例的一行中执行此操作。

#define STATIC_ARRAY(x, ...)   \
        static NSArray* x=nil; \
        static dispatch_once_t x##onceToken; \
        dispatch_once(&x##onceToken, ^{ x = @[ __VA_ARGS__ ]; });

Use example

使用的例子

    STATIC_ARRAY(foo, @"thing1", @"thing2", [NSObject new]);

#4


6  

It's pretty easy :

它很简单:

#define arrayTitle [NSArray arrayWithObjects: @"hi",@"foo",nil]

定义arrayTitle [NSArray arrayWithObjects: @"hi",@"foo",nil]

put before implementation and without semicolon.

在实现之前,不要使用分号。

hope it helps.

希望它可以帮助。

#5


3  

As for me, it is more convenient to use the following implementation for an array of constants

对于我来说,对一个常量数组使用以下实现更方便

static NSString * kHeaderTitles [3] = {@ "ACCOUNT DETAILS", @ "SOCIAL NETWORK", @ "SETTINGS"};
static int kNumbers[3] = {1, 2, 3};

#6


3  

I have a header file called "Constants.h" and within the next constant arrays:

我有一个头文件叫做“常量”。h”和在下一个常量数组中:

#define arrayOfStrings @[@"1", @"2", @"3", @"4"]
#define arraysOfIds @[@(1), @(2), @(3), @(4)]

Basically, when you call arrayOfStrings in your code, is replaced with @[@"1", @"2", @"3", @"4"] and the same thing with arraysOfIds.

基本上,当您在代码中调用arrayofstring时,会被替换为@[@"1",@"2",@"3",@"4"],arraysOfIds也是如此。