-1

私はこの問題に対する洗練された解決策があるかどうかを判断しようとしています。

いくつかのヘッダーでグローバルが定義されているとします。

Constants.h:

extern NSString *someGlobal;

そして、このグローバルを他のクラスで使用したいと思います。

Foo.m

NSString *localVariable = someGlobal;

次のようにグローバルを初期化すると、これはすべて正常に機能します。

Constants.m:

NSString *someGlobal = @"Some String Literal";

しかし、グローバルをコンパイル時定数ではないものに初期化する必要があるとしましょう。そのような場合、私は通常これを行います:

Constants.m:

@implementation Constants

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

@end

今、私はに潜在的な問題がありFoo.mます。Constantsを使用しようとしたときにクラスが参照されていない場合someGlobal、結果はになりnilます。回避策は次のとおりです。

Foo.m(または一部のアプリスタートアップコード):

[Constants class];

これにより、クラスのinitializeメソッドがトリガーされ、適切に初期化されます。を実行時に使用する前にこれを実行する限り、問題なく動作します。ConstantssomeGlobalsomeGlobal

[Constants classアプリの起動時に]などのコードを呼び出す必要なしに、コンパイル時定数以外でexternグローバルを初期化するためのより良い方法はありますか?

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 に答える