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

时间:2010-01-12 02:58:19

标签: objective-c initialization categories static-variables

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

答案 0 :(得分:25)

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

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

当程序开始和结束时,将自动调用这些函数。

答案 1 :(得分: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的实例,那么在程序结束之前它永远不会有dealloc的机会。

答案 2 :(得分:2)

您只需在使用之前将静态设置为已知点。例如,您可以设置NSApplication委托并让它在-applicationDidFinishLaunching:

中完成工作

答案 3 :(得分:1)

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

答案 4 :(得分:0)

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