Como posso me impedir de usar acidentalmente o ponteiro de um NSNumber quando quero o seu intvalue?
-
19-09-2019 - |
Pergunta
Um recurso do Java que eu realmente gosto é a auto -espião, na qual o compilador converte automaticamente entre primitivas e suas classes de wrapper.
Estou escrevendo um aplicativo de dados principal no Objective-C/Cacau e acho frustrante lidar com meus atributos inteiros programaticamente. Aqui está o porquê:
//img is a managed object that I have fetched
NSString* filename = [NSString stringWithFormat:@"image%d.png", [[img valueForKey:@"imageID"] intValue]];
Se eu esquecer o intValue
mensagem, o que às vezes faço, então o int que é passado para stringWithFormat:
é realmente o valor do ponteiro.
O problema é que isso acontece totalmente silenciosamente-nenhum erro ou aviso do compilador. Às vezes, vou gastar muito longa depuração quando essa coisa boba e estúpida é o problema.
Existe uma maneira de mudar meu estilo de programação ou minhas configurações de compilador para me impedir de ser pego nessa armadilha?
Editar: Eu não estava claro sobre o fato de que o exemplo acima é apenas um dos muitos lugares em que eu tenho problemas. Aqui está outro exemplo hipotético que não tem a ver com strings:
Entidade CollegeClass
tem dois atributos inteiros: courseNumber
e enrollmentLimit
. Digamos que eu queira comparar os números do curso:
//classFoo is a NSManagedObjects I've fetched
if ([[classFoo valueForKey@"courseNumber"] intValue] < 400) {
NSLog(@"undergraduate class");
}
Ou da mesma forma, suponha que eu queira calcular o limite médio de inscrição para todas as classes do departamento de CS.
Solução
… Suponha que eu queira calcular o limite médio de inscrição para todas as classes do departamento de CS.
Isso é fácil de fazer com Nsarray's e nsset's @avg
operador. Claro, isso retornará um NSNumber, que o colocará de volta no problema nº 2:
Digamos que eu queira comparar os números do curso:
//classFoo is a NSManagedObjects I've fetched if ([[classFoo valueForKey@"courseNumber"] intValue] < 400) { NSLog(@"undergraduate class"); }
Suponho que você quer dizer que o problema que você corre o risco é omitir o intValue
mensagem, comparando assim o objeto NSNumber id
para o int
.
O compilador oferece um aviso para essas comparações. No xcode, adicione -Wextra
para a sua configuração de construção "outras bandeiras C". Para mais opções de aviso, consulte A lista completa de avisos do GCC.
Outras dicas
Você pode usar %@ para converter um NSNumber diretamente em uma string em vez do %d.
Na verdade, ele levará qualquer classe baseada no NSOBject e a converterá em uma string, acredito.
Isso só é aplicável ao lidar com dados principais, mas se você usar Mogerator Para gerar classes para seus principais objetos de dados (que eu recomendaria de qualquer maneira), você pode usar -[propertyName]Value
métodos para acessar diretamente o valor correto para propriedades que retornam NSNumber
s:
// These two methods are identical when called on a class
// which was generated with MOGenerator
[[object imageID] intValue];
[object imageIDValue];
Ative as chamadas “TypeCheck para printf
/scanf
Aviso, se já não estiver. Isso não atualmente Ajuda com a formatação NS/CFString, mas eu arquivei uma solicitação de aprimoramento de radar (x-radar: // Problem/7375186) para isso. Você pode apresentar o seu próprio, é claro.