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

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

于 2010-01-12T03:00:00.107 回答
0

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

于 2010-01-12T03:31:43.763 回答