Como posso me impedir de usar acidentalmente o ponteiro de um NSNumber quando quero o seu intvalue?

StackOverflow https://stackoverflow.com/questions/1898091

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.

Foi útil?

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 NSNumbers:

// 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/scanfAviso, 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.

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