Инициализация статической переменной в категории Objective-C - PullRequest
9 голосов
/ 12 января 2010

Я пытался создать статическую переменную для хранения словаря изображений. К сожалению, лучший способ, который я смог найти для инициализации, это проверить каждую функцию, которая использовала переменную. Поскольку я создаю эту переменную внутри категории, я не могу просто инициализировать ее внутри инициализатора. Есть ли более аккуратный способ инициализации навигации BarImages?

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 ]

25 голосов
/ 12 января 2010
__attribute__((constructor))
static void initialize_navigationBarImages() {
  navigationBarImages = [[NSMutableDictionary alloc] init];
}

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

Эти функции будут вызываться автоматически при запуске и завершении программы.

10 голосов
/ 12 января 2010

Рассмотрим этот подход,

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 был создан, то он никогда не получит шанс на освобождение до конца программы.

2 голосов
/ 12 января 2010

Все, что вам нужно, это установить статический сигнал в известной точке перед его использованием. Например, вы можете установить делегат NSApplication и заставить его работать в -applicationDidFinishLaunching:

1 голос
/ 12 января 2010

Одним из вариантов является использование C ++. Измените расширение файла на .mm и замените = NULL на [[NSMutableDictionary alloc] init].

0 голосов
/ 12 января 2010

Вы можете добавить +initialize в файл .m вашей категории - вам просто нужно убедиться, что вы не разбили существующую реализацию, или вы получите общий выигрыш. (Очевидно, вы можете быть уверены в этом, если написали код, но с использованием стороннего кода это, вероятно, не лучший подход.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...