简体   繁体   English

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

[英]How do I declare an array as a constant in Objective-c?

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'

In short, you can't.简而言之,你不能。 Objective-C objects are, with the exception of NSString, only ever created at runtime.除了 NSString 之外,Objective-C 对象只能在运行时创建。 Thus, you can't use an expression to initialize them.因此,您不能使用表达式来初始化它们。

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) 声明NSArray *testArray没有const关键字,然后有一些代码来设置在应用程序生命周期中很早就调用的值。

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

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:在您的constants.h文件中,然后在您的constants.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).这显然是一个C数组而不是NSArray因此您不会像objectAtIndex:那样将所有有趣的方法附加到它上面,因此您可以在程序中的某处创建一个辅助函数,该函数使用 I 方法循环遍历所有字符串上面概述并返回一个NSArray (甚至NSMutableArray )。 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.但是,如果您正在做我所做的并且只需要在整个程序中使用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..这样做将所有字符串数组constants.h封装在constants.h ,并且通过在.pch文件中添加constants.h仍然可以在整个程序中使用,而不是仅为该值数组创建单例或使用很少的代码,这有点违背了constants文件的目的,因为它从constants文件中删除了实际的constants

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技巧,请在下面发表评论!

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]);

It's pretty easy :这很容易:

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

put before implementation and without semicolon.放在实现之前,没有分号。

hope it helps.希望能帮助到你。

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

I have a header file called "Constants.h" and within the next constant arrays:我有一个名为“Constants.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.基本上,当您在代码中调用 arrayOfStrings 时,它会被替换为 @[@"1", @"2", @"3", @"4"] 并且与 arraysOfIds 相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM