初始化Objective-C类别中的静态变量

时间:2022-08-07 10:46:59

I was trying to create a static variable to store a dictionary of images. Unfortunately, the best way I could find to initialise it was to check in each function that used the variable. Since I am creating this variable inside a category, I can't just initialise it inside the initialiser. Is there a neater way of initialising navigationBarImages?

我试图创建一个静态变量来存储图像字典。不幸的是,我可以找到初始化它的最好方法是检入使用该变量的每个函数。由于我在一个类别中创建了这个变量,我不能只在初始化器中初始化它。有没有更简洁的初始化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

5 个解决方案

#1


24  

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

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

These function will be called automatically when the program starts and ends.

程序启动和结束时将自动调用这些函数。

#2


10  

Consider this approach,

考虑这种方法,

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

then whenever you woulde use navigationBarImages, replace it with navigationBarImages(), like this:

然后无论何时你使用navigationBarImages,用navigationBarImages()替换它,如下所示:

change

NSString *imageName=[navigationBarImages objectForKey:self];

to

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

If the function call overhead bothers you, maybe use a temporary variable to catch the return of navigationBarImages(),

如果函数调用开销困扰你,可能使用临时变量来捕获navigationBarImages()的返回,

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

The drawback is once you called navigationBarImages(), the instance of NSMutableDictionary got created, then it'll never get chance to dealloc until the end of the program.

缺点是一旦你调用了navigationBarImages(),NSMutableDictionary的实例就被创建了,那么在程序结束之前它永远不会有dealloc的机会。

#3


2  

All you need is to set your static once at a known point before it is used. For example, you can set an NSApplication delegate and have it do the work in -applicationDidFinishLaunching:

您所需要的只是在使用之前将静态设置为已知点。例如,您可以设置NSApplication委托并让它在-applicationDidFinishLaunching中完成工作:

#4


1  

One option is to use C++. Change the file's extension to .mm and replace = NULL with [[NSMutableDictionary alloc] init].

一种选择是使用C ++。将文件的扩展名更改为.mm,并使用[[NSMutableDictionary alloc] init]替换= NULL。

#5


0  

You could add +initialize in the .m file of your category — you'll just need to make sure you're not smashing an existing implementation or you'll get general wonkiness. (Obviously, you can be sure of this if you wrote the code, but with third-party code, this is probably not the best approach.)

你可以在你的类别的.m文件中添加+初始化 - 你只需要确保你没有粉碎现有的实现,否则你会得到普遍的好感。 (显然,如果您编写代码,可以确定这一点,但使用第三方代码,这可能不是最好的方法。)

#1


24  

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

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

These function will be called automatically when the program starts and ends.

程序启动和结束时将自动调用这些函数。

#2


10  

Consider this approach,

考虑这种方法,

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

then whenever you woulde use navigationBarImages, replace it with navigationBarImages(), like this:

然后无论何时你使用navigationBarImages,用navigationBarImages()替换它,如下所示:

change

NSString *imageName=[navigationBarImages objectForKey:self];

to

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

If the function call overhead bothers you, maybe use a temporary variable to catch the return of navigationBarImages(),

如果函数调用开销困扰你,可能使用临时变量来捕获navigationBarImages()的返回,

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

The drawback is once you called navigationBarImages(), the instance of NSMutableDictionary got created, then it'll never get chance to dealloc until the end of the program.

缺点是一旦你调用了navigationBarImages(),NSMutableDictionary的实例就被创建了,那么在程序结束之前它永远不会有dealloc的机会。

#3


2  

All you need is to set your static once at a known point before it is used. For example, you can set an NSApplication delegate and have it do the work in -applicationDidFinishLaunching:

您所需要的只是在使用之前将静态设置为已知点。例如,您可以设置NSApplication委托并让它在-applicationDidFinishLaunching中完成工作:

#4


1  

One option is to use C++. Change the file's extension to .mm and replace = NULL with [[NSMutableDictionary alloc] init].

一种选择是使用C ++。将文件的扩展名更改为.mm,并使用[[NSMutableDictionary alloc] init]替换= NULL。

#5


0  

You could add +initialize in the .m file of your category — you'll just need to make sure you're not smashing an existing implementation or you'll get general wonkiness. (Obviously, you can be sure of this if you wrote the code, but with third-party code, this is probably not the best approach.)

你可以在你的类别的.m文件中添加+初始化 - 你只需要确保你没有粉碎现有的实现,否则你会得到普遍的好感。 (显然,如果您编写代码,可以确定这一点,但使用第三方代码,这可能不是最好的方法。)