NSInteger myInt = 1804809223;
NSLog(@"%i", myInt); <====
O código acima produz um erro:
Valores do tipo 'NSInteger' não devem ser usados como argumentos de formato; adicione uma conversão explícita a 'long'
A NSLog
mensagem corrigida é realmente NSLog(@"%lg", (long) myInt);
. Por que preciso converter o valor inteiro de myInt
para long
se eu quero que o valor seja exibido?
objective-c
xcode
casting
nsinteger
Daniel Lee
fonte
fonte
NSLog(@"%ld", (long) myInt);
, olong
elenco é torná-lo corresponder-se com ol
qualificador de%ld
, mas tudo isso é desnecessário comoNSLog(@"%d", myInt);
é suficiente (uma vez que podemos ver quemyInt
não élong
. A linha inferior, você jogamyInt
se estiver usando longa qualificador em formato string, mas não há necessidade de usar um qualificador de longo formato de corda oulong
fundido aqui.NSInteger
é longa), mas parece que você está compilando com o destino do OS X (onde está ).NSInteger
long
Respostas:
Você recebe esse aviso se compilar no OS X (64 bits), porque nessa plataforma
NSInteger
é definido comolong
e é um número inteiro de 64 bits. O%i
formato, por outro lado, é paraint
, que é de 32 bits. Portanto, o formato e o parâmetro real não coincidem em tamanho.Como
NSInteger
é de 32 ou 64 bits, dependendo da plataforma, o compilador recomenda adicionar uma conversãolong
geralmente.Atualização: como o iOS 7 também suporta 64 bits agora, você pode receber o mesmo aviso ao compilar para iOS.
fonte
NSLog(@"%ld", (long) myInt)
, ele funciona corretamente em 32 e 64 bits.long myInt = [myNumber longValue];
. Porém, muitos métodos da (Core) Foundation usam NS (U) Inteiro como parâmetro ou valor de retorno, portanto o problema geral permanece. Também pode fazer sentido no seu aplicativo usar o NS (U) Inteiro para obter um intervalo maior disponível em dispositivos de 64 bits.Você não precisa converter para nada se os especificadores de formato corresponderem aos seus tipos de dados. Veja a resposta de Martin R para obter detalhes sobre como
NSInteger
é definido em termos de tipos nativos.Portanto, para o código que deve ser criado para ambientes de 64 bits, você pode escrever suas instruções de log desta maneira:
enquanto em ambientes de 32 bits, você pode escrever:
e tudo funcionará sem elencos.
Uma razão para usar as conversões de qualquer maneira é que um bom código tende a ser portado entre plataformas, e se você converter suas variáveis explicitamente, ele será compilado de maneira limpa em 32 e 64 bits:
E observe que isso é verdade não apenas para as instruções NSLog, que são apenas auxiliares de depuração, mas também para
[NSString stringWithFormat:]
e as várias mensagens derivadas, que são elementos legítimos do código de produção.fonte
Em vez de passar um NSInteger para o NSLog, basta passar um NSNumber. Isso contornará todos os elencos e a escolha do especificador de formato de sequência correto.
Também funciona para o NSUIntegers sem precisar se preocupar com isso. Veja a resposta para o NSInteger e o NSUInteger em um ambiente misto de 64 bits / 32 bits
fonte
Ele mantém o aviso durante o uso
NSLog(@"%ld", (long)myInt);
, mas para de avisar após a declaração de alteraçãolong myInt = 1804809223;
no iOS 10.fonte
O OS X usa vários tipos de dados - NSInteger, NSUInteger, CGFloat e CFIndex - para fornecer um meio consistente de representação de valores em ambientes de 32 e 64 bits. Em um ambiente de 32 bits, NSInteger e NSUInteger são definidos como int e unsigned int, respectivamente. Em ambientes de 64 bits, o NSInteger e o NSUInteger são definidos como longos e sem assinatura, respectivamente. Para evitar a necessidade de usar diferentes especificadores do tipo printf, dependendo da plataforma, você pode usar os especificadores mostrados neste link para ambientes de 32 e 64 bits.
fonte