09 Set, 2011 12:00

2 dicas simples para trabalhar com NSNull

Apesar de substituir o nil, NSNull possui uma diferença fundamental: a chamada de métodos de NSNull causa erros, enquanto a nil sempre retorna nil.

id meuNil = nil;
[meuNil meuMetodoQualquer]; //retorna nil!

id meuNull = [NSNull null];
[meuNil meuMetodoQualquer] //'NSInvalidArgumentException', reason: '-[NSNull meuMetodoQualquer]: unrecognized selector sent to instance

Esse comportamento obriga-nos a sempre tratar a possibilidade de um dado objeto ser NSNull.

//meuObjeto pode ser NSNull em alguns cenários
if ((NSNull *)meuObjeto != [NSNull null]) {
    //meuObjeto é válido, então eu faço uma determinada ação
}
else {
    //meuObjeto é NSNull então eu faço o tratamento
}

Para facilitar a nossa vida, criamos duas técnicas que passaremos para vocês agora.

Dica 1: Convertendo NSNull em nil automaticamente

É comum o caso em que você simplesmente queira que, onde houver um NSNull, este se comporte como um nil - por exemplo, para atribuir a uma segunda variável. O código padrão para tratar esse comportamento poderia ser:

if ((NSNull *)meuObjeto != [NSNull null]) {
    outroObjeto.propriedadeQualquer = meuObjeto;
}
else {
    outroObjeto.propriedadeQualquer = nil;
}

Numa situação onde você esteja realizando muitas atribuições como a acima (como, por exemplo, copiando diversos valores de um NSDictionary para o seu objeto), seu código poderia ficar bem extenso. Para evitar isso, poderíamos fazer algo como

outroObjeto.propriedadeQualquer = [meuObjeto orNil];

Simples, não? Se meuObjeto for qualquer objeto válido, orNil retornará o próprio objeto. Caso contrário, retornará nil.

Mas como fazer esse truque funcionar? Resposta: Categories! Em suma, no Objective C é possível adicionar métodos a uma classe pré-existente sem precisar criar uma subclasse. O código para isso é muito trivial.

NSObject+NSNullExtras.h

@interface NSObject (NSNullExtras) 

- (id)orNil;

@end

NSObject+NSNullExtras.m

#import "NSObject+NSNullExtras.h"

@implementation NSObject (NSNullExtras)

- (id)orNil {
    return self;
}

@end

@implementation NSNull (NSNullExtras)

- (id)orNil {
    return nil;
}

@end

Repare que é necessário criar o método em NSObject para que qualquer objeto possa responder a essa chamada e sobrescrevê-lo em NSNull.

Para utilizar, basta importar NSObject+NSNullExtras.h onde for necessário.

Dica 2: Descrição padrão

Outro caso recorrente é o de chamar o método description para obter um NSString a partir do seu objeto. NSNull, contudo, vira "<null>", o que pode não ser interessante.

Para resolver essa situação, criamos o método descriptionWithDefault:. Ex.

self.label.text = [meuObjeto descriptionWithDefault:@"não informado"];

Se meuObjeto for válido, o label do exemplo receberá a sua descrição normal, caso contrário, receberá a string "não informado". A técnica para esse método é semelhante a do orNil. Você pode baixar o código de ambos aqui.

Ao navegar neste site, você consente o uso de cookies nossos e de terceiros, que coletam informações anônimas e são essenciais para melhorar sua experiência em nosso site.