Inicializando uma variável estática na categoria Objective-C
-
20-09-2019 - |
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
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.)