在协议中定义一个 NSArray 常量

Posted

技术标签:

【中文标题】在协议中定义一个 NSArray 常量【英文标题】:Defining an NSArray Constant in a Protocol 【发布时间】:2016-12-16 12:00:08 【问题描述】:

我有一个协议类,我在其中定义了多个字符串常量和包含这些字符串的数组常量。我正在移植一个 android 项目。

在我的Constants.h 中,我声明NSStringNSArray 常量如下:

#imports.....

extern NSString *const constant1;
extern NSString *const constant2;

extern NSArray *const constantArr;

@protocol.....

然后在我的Constants.m 中,我定义了这些常量:

#import "Constant.h"

NSString *const constant1 = @"Constant1";
NSString *const constant2 = @"Constant2";

//I get an error at this line
NSArray *const constantArr = [NSArray arrayWithObject: constant1, constant2, nil];

定义 NSArray 时出现错误,显示为 Initializer element is not a compile-time constant。我相信我可能会以错误的方式初始化 NSArray 常量。

有没有人遇到过类似的问题或知道初始化 NSArray 常量的方法?谢谢

【问题讨论】:

您不能使用arrayWithObject 构造函数,因为它会在运行时创建数组。您可以使用 @[constant1,constant2] 数组字面量语法创建数组 在我的 .h 和 .m 中,我都尝试了NSArray *const constantArr = @[constant1, constant2];,但仍然遇到同样的错误。 您需要输入@"Comstant1"@"Constant2" 字符串,而不是在数组定义中使用变量 刚试过NSArray *const constantArr = @[@"Constant1", @"Constant2"];,我仍然遇到同样的错误。我一定是在做傻事? 经过更多研究,您无法通过这种初始化程序创建常量 Objective-C 对象。您需要在该对象初始化程序中创建该数组作为某个对象的属性。 【参考方案1】:

问题是您试图在编译时使用运行时功能,例如实例化数组([NSArray arrayWithObjects:] 和文字形式 @[] 都解析为运行时分配)。

常量字符串不会受此影响,因为编译器可以在二进制文件的data 段中分配字符串所需的字节,但是数组不能这样做。

您需要的是一段代码,该代码将在您的应用程序启动时执行,从而能够访问运行时功能。

好消息是您可以通过__attribute__((constructor)) 修饰符实现此目的,该修饰符告诉编译器在加载二进制文件时执行修饰函数,这是否巧合是在应用程序启动时,在任何AppDelegate 代码执行之前.

NSArray *constantAr;

//...

__attribute__((constructor))
static void initialize_constants() 
    constantArr = @[constant1, constant2];

缺点是您需要放弃const 修饰符,因此数组将不再是真正的常量。

【讨论】:

非常感谢您的明确回答。在我的脑海中是有道理的,我必须整合这种方法。我可以放弃真正的常数。

以上是关于在协议中定义一个 NSArray 常量的主要内容,如果未能解决你的问题,请参考以下文章

oc70--NSArray1

NSPredicate的使用

将 JSON 放入数组中

如何使用按钮移动图像?

Swift 无法将 NSNumber 桥接到 Float [重复]

如何从自定义类中检索 NSArray