Pergunta

Eu estava tentando criar uma variável estática para armazenar um dicionário de imagens. Infelizmente, a melhor maneira de encontrar para inicializar foi verificar cada função que usava a variável. Como estou criando essa variável dentro de uma categoria, não posso simplesmente inicializá -la dentro do inicializador. Existe uma maneira mais limpa de inicializar os barimágios de navegação?

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
Foi útil?

Solução

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

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

Essas funções serão chamadas automaticamente quando o programa começar e terminar.

Outras dicas

Considere esta abordagem,

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

então sempre que você usaria NavigationBarimages, substitua -o por NavigationBarimages (), assim:

mudança

NSString *imageName=[navigationBarImages objectForKey:self];

para

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

Se a chamada de função indicar você, talvez use uma variável temporária para obter o retorno de NavigationBarimages (),

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

A desvantagem é que, depois que você chamou o NavigationBarimages (), a instância do NSMutableDictionary foi criada, nunca terá chance de negociar até o final do programa.

Tudo o que você precisa é definir sua estática uma vez em um ponto conhecido antes de ser usado. Por exemplo, você pode definir um delegado de nsapplicação e fazer com que faça o trabalho em -applicationDidFinishLaunching:

Uma opção é usar C ++. Altere a extensão do arquivo para .mm e substitua = NULL com [[NSMutableDictionary alloc] init].

Você pode adicionar +initialize No arquivo .m da sua categoria - você só precisará garantir que não esteja esmagando uma implementação existente ou obterá o Wonkiness Geral. (Obviamente, você pode ter certeza disso se você escreveu o código, mas com o código de terceiros, provavelmente não é a melhor abordagem.)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top