9

画像の辞書を格納する静的変数を作成しようとしていました。残念ながら、変数を初期化するために見つけた最善の方法は、変数を使用する各関数をチェックインすることでした。この変数はカテゴリ内で作成しているため、初期化子内で初期化することはできません。navigationBarImages を初期化するより適切な方法はありますか?

static NSMutableDictionary *navigationBarImages = NULL;

@implementation UINavigationBar(CustomImage)
//Overrider to draw a custom image
- (void)drawRect:(CGRect)rect
{
    if(navigationBarImages==NULL){
        navigationBarImages=[[NSMutableDictionary alloc] init];
    }
    NSString *imageName=[navigationBarImages objectForKey:self];
    if (imageName==nil) {
        imageName=@"header_bg.png";
    }
    UIImage *image = [UIImage imageNamed: imageName];
    [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}

//Allow the setting of an image for the navigation bar
- (void)setImage:(UIImage*)image
{
    if(navigationBarImages==NULL){
        navigationBarImages=[[NSMutableDictionary alloc] init];
    }
    [navigationBarImages setObject:image forKey:self];
}
@end
4

5 に答える 5

25
__attribute__((constructor))
static void initialize_navigationBarImages() {
  navigationBarImages = [[NSMutableDictionary alloc] init];
}

__attribute__((destructor))
static void destroy_navigationBarImages() {
  [navigationBarImages release];
}

これらの関数は、プログラムの開始時と終了時に自動的に呼び出されます。

于 2010-01-12T06:00:13.637 に答える
10

このアプローチを検討してください。

static NSMutableDictionary *navigationBarImages()
{
    static NSMutableDictionary *dict = NULL;
    if(dict == NULL)
    {
        dict = [[NSMutableDictionary alloc] init];
    }
    return [[dict retain] autorelease];
}

次に、 navigationBarImages を使用するときはいつでも、次のように、それをnavigationBarImages()に置き換えます。

変化する

NSString *imageName=[navigationBarImages objectForKey:self];

NSString *imageName=[navigationBarImages() objectForKey:self];

関数呼び出しのオーバーヘッドが気になる場合は、一時変数を使用して、navigationBarImages() の戻り値をキャッチしてください。

NSMutableDictionary *dict = navigationBarImages();
[dict doSomething];
[dict doSomething];

欠点は、navigationBarImages() を呼び出すと、NSMutableDictionary のインスタンスが作成されると、プログラムが終了するまで割り当てを解除する機会が得られないことです。

于 2010-01-12T03:27:34.100 に答える
2

必要なのは、静的を使用する前に既知のポイントに一度設定することだけです。たとえば、NSApplicationデリゲートを設定して、-applicationDidFinishLaunching:

于 2010-01-12T03:10:05.193 に答える
1

1 つのオプションは、C++ を使用することです。ファイルの拡張子を .mm に変更し= NULL[[NSMutableDictionary alloc] init].

于 2010-01-12T03:00:00.107 に答える
0

カテゴリの .m ファイルに追加することもでき+initializeます — 既存の実装を壊していないことを確認する必要があるだけです。(明らかに、コードを書いた場合はこれを確信できますが、サードパーティのコードでは、これはおそらく最善の方法ではありません。)

于 2010-01-12T03:31:43.763 に答える