Como converter um NSInteger em um int?


97

Por exemplo, ao passar uma valuemensagem para uma NSIntegerinstância como esta

[a value] isso causa um EXC_BAD_ACCESS.

Então, como converter um NSIntegerpara int?

Se for relevante, apenas pequenos números <32 são usados.


2
Você parece bastante confuso. [um valor] sugere que você espera que a seja um objeto, mas que é um NSInteger no momento. "Converter" em um int não resolverá esse problema.
— Mike Abdullah

Respostas:


205

Ta da:

NSInteger myInteger = 42;
int myInt = (int) myInteger;

NSIntegernada mais é do que um int de 32/64 bits. (ele usará o tamanho apropriado com base em qual sistema operacional / plataforma você está executando)


13
Para ser preciso, acho que NSInteger é um int em plataformas de 32 bits e um longo em plataformas de 64 bits.
— Frédéric Adda

5
Recebo um aviso usando o "casting" sugerido: A conversão implícita perde a precisão do inteiro: 'NSUInteger' (também conhecido como 'unsigned long') para 'int'
— djcj

@djcj, sim, a resposta não está correta para novos SDKs. Eu acho que.
— Azik Abdullah

Não seria muito mais fácil simplesmente colocar (int) na frente do NSInteger? Por exemplo, (int) myInteger sempre que quiser chamar a forma inteira, de forma que não seja necessário criar uma nova variável.
— chandhooguy

2
@chandhooguy por que você está tentando evitar uma nova variável?
— Dan Rosenstark

28

Se você quiser fazer isso embutido, apenas transmita o NSUIntegerou NSIntegerpara um int:

int i = -1;
NSUInteger row = 100;
i > row // true, since the signed int is implicitly converted to an unsigned int
i > (int)row // false

1
Só por curiosidade, por que você está postando uma resposta 2 anos após o fato em uma questão que já tem uma resposta aceita com votos de dois dígitos? Especialmente porque a sua é apenas uma reformulação dessa resposta.
— Lily Ballard

6
Porque minha resposta é uma única linha (usando uma conversão de tipo embutido - o (int)), que eu acho que é o que o OP deseja. Eu mesmo examinei isso e percebi que todas as respostas sobre o assunto eram multilinhas.
— Samuel Clay

2
A resposta aceita demonstra uma conversão implícita usando uma única linha. A resposta do Abizern explica que uma conversão implícita acontecerá se você tentar usar um NSIntegervalor no lugar de um int. Em nenhum dos casos é uma solução multilinha.
— Lily Ballard

25
Eu deveria ter sido mais claro. Visto que esta é uma pergunta um tanto novata, pode não ser óbvio para o programador novato que ele pode converter inline com uma expressão (int). As outras respostas não mostram isso e acho que ajuda qualquer pessoa que tropeçar nesta página.
— Samuel Clay

4
E eu tropecei nesta página ainda outro ano e meio depois, precisando do elenco relacionado ao NSUInteger especificamente. Obrigado, Samuel!
— leanne

18

Não tenho certeza sobre as circunstâncias em que você precisa converter um NSIntegerem um int.

NSInteger é apenas um typedef:

NSInteger Usado para descrever um número inteiro independentemente de você estar construindo para um sistema de 32 ou 64 bits.

#if __LP64__ || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64 
typedef long NSInteger;
#else
typedef int NSInteger;
#endif

Você pode usar NSIntegerqualquer lugar que usar intsem convertê-lo.


2
Aqui está um bom motivo para converter um NSUinteger em um int: comparações de valor. (int i = -1)> (NSUinteger j = 14) converte o int em não assinado, o que significa -1> 14, que não é o que você deseja.
— Samuel Clay

1
@SamuelClay. Um bom ponto quando usado em casos específicos. Pessoalmente, eu converteria um NSUInteger em um uint. Contudo. A questão era sobre a conversão de NSInteger, não NSUInteger.
— Abizern

Usei apenas um int não assinado para ilustrar uma armadilha comum. É o mesmo tipo de elenco para ambos, como minha resposta demonstra. Não é um problema difícil, mas é bastante comum e ainda não vi ninguém recomendar uma resposta de uma linha.
— Samuel Clay

0

Normalmente usado em UIsegmentedControl, "erro" aparece ao compilar em 64 bits em vez de 32 bits, uma maneira fácil de não passá-lo para uma nova variável é usar estas dicas, add (int) :

[_monChiffre setUnite:(int)[_valUnites selectedSegmentIndex]];

ao invés de :

[_monChiffre setUnite:[_valUnites selectedSegmentIndex]];
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.