Objective-Cカテゴリの静的変数の初期化
-
20-09-2019 - |
質問
画像の辞書を保存するために静的変数を作成しようとしていました。残念ながら、私がそれを初期化するために見つけることができる最良の方法は、変数を使用した各関数をチェックインすることでした。カテゴリ内でこの変数を作成しているため、InitialIser内で初期化することはできません。 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
解決
__attribute__((constructor))
static void initialize_navigationBarImages() {
navigationBarImages = [[NSMutableDictionary alloc] init];
}
__attribute__((destructor))
static void destroy_navigationBarImages() {
[navigationBarImages release];
}
これらの関数は、プログラムが開始および終了すると、自動的に呼び出されます。
他のヒント
このアプローチを考慮してください、
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()と呼ばれると、nsmutedabledictionaryのインスタンスが作成され、プログラムの終了まで取引する機会が得られません。
必要なのは、使用される前に既知のポイントで静的を一度設定することです。たとえば、NSApplication Delegateを設定して、 -applicationDidFinishLaunching:
1つのオプションは、C ++を使用することです。ファイルの拡張子を.mmに変更して置き換えます = NULL
と [[NSMutableDictionary alloc] init]
.
追加できます +initialize
カテゴリの.mファイルでは、既存の実装を破壊しないことを確認する必要があります。 (明らかに、コードを書いた場合、これを確信できますが、サードパーティのコードでは、これはおそらく最良のアプローチではありません。)