繁体   English   中英

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

[英]Initialising a static variable in Objective-C category

我试图创建一个静态变量来存储图像字典。 不幸的是,我可以找到初始化它的最好方法是检入使用该变量的每个函数。 由于我在一个类别中创建了这个变量,我不能只在初始化器中初始化它。 有没有更简洁的初始化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(),就会创建NSMutableDictionary的实例,那么在程序结束之前它永远不会有dealloc的机会。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM