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

And*_*rew 63 arrays constants objective-c

以下代码给出了错误:

//  constants.h
extern NSArray const *testArray;
Run Code Online (Sandbox Code Playgroud)
//  constants.m
NSArray const *testArray = [NSArray arrayWithObjects:  @"foo", @"bar", nil];
Run Code Online (Sandbox Code Playgroud)

我得到的错误是
initializer element is not constant

或者,如果我拿走指针指针(*),我得到:
statically allocated instance of Objective-C class 'NSArray'

bbu*_*bum 69

总之,你不能.除NSString常量外,Objective-C对象仅在运行时创建,因此,您无法使用表达式初始化它们.

有一些方法.

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

(2)声明一个返回数组的方便类方法,然后static NSArray *myArray在该方法中使用a 并将其视为单例(搜索SO为"objective-c singleton",以获得关于如何实例化的大量答案).

  • 如果你只处理问题中的`NSStrings`数组,你可以在常量文件中创建一个`C`样式数组,然后使用一些`C`方法来访问这些值.见[我的答案如下](http://stackoverflow.com/a/11485727/630996) (5认同)
  • @bbum - 即使使用`@ [...]`糖也是如此,是吗? (2认同)
  • 有人可能会说,现在块是完全保留的可保留对象类型,它们是第二种类型的Objective-C对象,其中编译器知道布局并可以创建常量实例.可以从块文字初始化静态存储持续时间变量. (2认同)

Ang*_*loS 33

派对有点晚了,但由于你没有在程序过程中更改值,如果你只处理字符串,你可以通过使用C数组声明你的数组来做到以下几点:

extern NSString * const MY_CONSTANT_STRING_ARRAY[];
Run Code Online (Sandbox Code Playgroud)

在你的constants.h文件中,然后constants.m你可以在其中添加对象,如下所示:

NSString * const MY_CONSTANT_STRING_ARRAY[] = { @"foo", @"bar" };
Run Code Online (Sandbox Code Playgroud)

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

这显然是一个C数组而不是一个NSArray所以你没有得到所有有趣的方法objectAtIndex:,所以你可以在你的程序中的某个地方创建一个辅助函数,它使用我上面概述的方法遍历所有字符串并返回一个NSArray(NSMutableArray甚至).但是,如果你正在做我自己的事情,只需要NSString在整个程序中使用一系列常量值,这种方法效果最好.

这样做,这样封装了所有的字符串数组contants的constants.h,并且仍然是整个程序可以通过添加constants.h在你的.pch文件,而不是只为这阵值创造了单或设置阵列用很少的代码,这八九不离十失败的目的一个constants文件,因为它删除了文件中的实际常量constants..

编辑@ JesseGumpo的评论:

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

//.h
extern int SIZE_OF_MY_CONSTANTS_ARRAY;  

///.m
int SIZE_OF_MY_CONSTANTS_ARRAY = 2;
Run Code Online (Sandbox Code Playgroud)

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

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

是的,这不会动态捕获数组的大小,但是如果你在常量文件中声明一个数组,你从一开始就已经知道了该数组的大小,那么即使它增加了两行代码,仍然完成了在常量文件中使用数组的任务.

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

  • "sizeof(MY_CONSTANT_STRING_ARRAY)/ sizeof(MY_CONSTANT_STRING_ARRAY [0])"会这样做 (7认同)

小智 9

这是一个宏,可以在一行中为方法范围中的静态实例执行此操作.

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

使用示例

    STATIC_ARRAY(foo, @"thing1", @"thing2", [NSObject new]);
Run Code Online (Sandbox Code Playgroud)


小智 6

至于我,对于常量数组使用以下实现更方便

static NSString * kHeaderTitles [3] = {@ "ACCOUNT DETAILS", @ "SOCIAL NETWORK", @ "SETTINGS"};
static int kNumbers[3] = {1, 2, 3};
Run Code Online (Sandbox Code Playgroud)


Hel*_*miB 5

这很简单:

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

在实施之前放,没有分号.

希望能帮助到你.

  • 这并没有真正给你一个常量数组,它只是在你每次使用`arrayTitle`时生成一个新数组, (56认同)
  • 但是,它确实帮助其他人稍后访问该帖子,他们只想在头文件中声明,但不关心是否保持常量. (8认同)