-1

我正在尝试确定是否有一个优雅的解决方案来解决这个问题。

假设我在某个标头中定义了一个全局变量:

常量.h:

extern NSString *someGlobal;

然后我希望在其他类中使用这个全局:

Foo.m

NSString *localVariable = someGlobal;

如果我像这样初始化全局,这一切都很好:

常数.m:

NSString *someGlobal = @"Some String Literal";

但是可以说我需要将全局初始化为不是编译时常量的东西。在这种情况下,我通常会这样做:

常数.m:

@implementation Constants

+ (void)initialize {
    someGlobal = ... // some non-trivial initialization
}

@end

现在我有一个潜在的问题Foo.mConstants如果我尝试使用时没有对类进行引用someGlobal,则结果为nil. 一种解决方法是:

Foo.m(或在某些应用程序启动代码中):

[Constants class];

这将触发类的initialize方法ConstantssomeGlobal正确初始化。只要这是在任何运行时使用之前完成的someGlobal,一切都会正常工作。

有没有更好的方法来初始化具有非编译时间常量的外部全局变量,而无需在应用程序启动时调用诸如[Constants class] 之类的代码?

4

3 回答 3

4

Objective-C 中更惯用的方式是使用单例而不是多个全局变量。方法如下:

@interface Globals
@property (readwrite,nonatomic) NSString *myString;
@property (readwrite,nonatomic) int myInt;
+(Globals*) instance;
@end

+(Globals*) instance {
    static dispatch_once_t once;
    static Globals *inst;
    dispatch_once(&once, ^{
        inst = [[Globals alloc] init];
        inst.myString = @"Some String Literal";
        inst.myInt = 42;
    });
    return inst;
}

现在你可以像这样使用你的全局变量:

NSLog(@"Global string: %@", [Globals instance].myString);
NSLog(@"Global string: %d", [Globals instance].myInt);
于 2013-02-23T01:32:29.240 回答
3

不,没有更好的办法。从逻辑上讲,如果必须在初始化变量之前执行某些代码,则必须采取措施确保发生这种情况。

您可以安排程序代码的流程,以确保在Constants执行任何其他需要它的代码之前初始化该类。例如,通过调整程序中事物的初始化顺序,并按照代码执行的顺序main()自上而下地向自己证明它是有效的。但除此之外(在任何情况下都是最安全的事情),您将使用您的技术强制它在使用之前使其有效。

于 2013-02-23T01:32:06.727 回答
1

就像 dasblinkenlight 的回答一样,这可能不是您正在寻找的,但它是另一种方法。

我会创建返回您正在寻找的值的类方法,如下所示:

+(NSString *)someConstant {
    static NSString *constant;
    if(constant == nil)
        constant = //your initialization here;
    return constant;
}

然后你需要在哪里使用它只需调用[Constants someConstant];

其他随机想法: 不是某个编译时值的常量并不是 extern 变量的真正用途,并且此方法可确保每次使用变量时都对其进行初始化。使用常量的类无论如何都必须知道你的类,否则它不会导入它的头文件

于 2013-02-24T01:48:17.377 回答