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.

Jeffrey
fonte
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)

Dave DeLong
fonte
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
Samuel Clay
fonte
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.

Abizern
fonte
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]];
grominet
fonte