Quando devo usar NSInteger
vs. int ao desenvolver para iOS? Vejo no código de exemplo da Apple que eles usam NSInteger
(ou NSUInteger
) ao passar um valor como argumento para uma função ou retornar um valor de uma função.
- (NSInteger)someFunc;...
- (void)someFuncWithInt:(NSInteger)value;...
Mas dentro de uma função que eles estão usando int
para rastrear um valor
for (int i; i < something; i++)
...
int something;
something += somethingElseThatsAnInt;
...
Eu li (me disseram) que NSInteger
é uma maneira segura de fazer referência a um número inteiro em um ambiente de 64 ou 32 bits, então por que usar int
?
fonte
int
seja mais adequado para até umlong
. Talvez você saiba que não excederá um determinado intervalo e, portanto, acha que será mais eficiente em termos de memória simplesmente usarint
.NSInteger
é passar valores de e para uma API que a especifica. Fora isso, não tem vantagem sobre um int ou um longo. Pelo menos com um int ou um longo, você sabe quais especificadores de formato usar em uma declaração printf ou similar.Por que usar
int
?A Apple usa
int
porque, para uma variável de controle de loop (que é usada apenas para controlar as iterações do loop), oint
tipo de dados é bom, tanto no tamanho do tipo de dados quanto nos valores que ele pode conter para o loop. Não há necessidade de tipo de dados dependente da plataforma aqui. Para uma variável de controle de loop, mesmo um de 16 bitsint
fará a maior parte do tempo.A Apple usa
NSInteger
para um valor de retorno de função ou para um argumento de função, porque nesse caso o tipo de dados [tamanho] é importante , porque o que você está fazendo com uma função é comunicar / transmitir dados com outros programas ou com outros trechos de código; veja a resposta para Quando devo usar o NSInteger vs int? na sua própria pergunta ...fonte
OS X é "LP64". Isso significa que:
int
é sempre de 32 bits.long long
é sempre de 64 bits.NSInteger
elong
são sempre do tamanho de ponteiros. Isso significa que eles são de 32 bits em sistemas de 32 bits e 64 bits em sistemas de 64 bits.O motivo pelo qual o NSInteger existe é que muitas APIs herdadas foram usadas incorretamente
int
vez delong
conter variáveis do tamanho de ponteiros, o que significava que as APIs precisavam mudar deint
paralong
nas versões de 64 bits. Em outras palavras, uma API teria assinaturas de funções diferentes, dependendo da compilação de arquiteturas de 32 ou 64 bits.NSInteger
pretende mascarar esse problema com essas APIs herdadas.Em seu novo código, o uso
int
se você precisa de uma variável de 32 bits,long long
se você precisa de um número inteiro de 64-bit, elong
ouNSInteger
se você precisar de uma variável ponteiro porte.fonte
int32_t
. Se você precisar de um número inteiro de 64 bitsint64_t
. Se você precisar de uma variável do tamanho de um ponteiro, useintptr_t
.<stdint.h>
tipos existem para esse fim.LP64
não garante quelong long
sejam 64 bits. UmaLP64
plataforma pode optar por terlong long
um número inteiro de 128 bits.Se você se interessar pela implementação do NSInteger:
Simplesmente, o NSInteger typedef faz um passo para você: se a arquitetura é de 32 bits, usa
int
, se é de 64 bits, usalong
. Usando o NSInteger, você não precisa se preocupar com a arquitetura em que o programa está sendo executado.fonte
long long
. Portanto, todos os tipos numéricos usarão o mesmo especificador de tipo.NSLog("%@", @(1123));
NSLog("%li", (long)theNSInteger);
Você deve usar o NSIntegers se precisar compará-los com valores constantes, como NSNotFound ou NSIntegerMax, pois esses valores diferem nos sistemas de 32 e 64 bits, portanto, valores de índice, contagens e similares: use NSInteger ou NSUInteger.
Não faz mal usar o NSInteger na maioria das circunstâncias, exceto pelo fato de ocupar o dobro de memória. O impacto na memória é muito pequeno, mas se você tiver uma quantidade enorme de números flutuando a qualquer momento, poderá fazer diferença usar ints.
Se você usar o NSInteger ou o NSUInteger, convém convertê-los em inteiros longos ou inteiros longos não assinados ao usar seqüências de caracteres de formato, pois o novo recurso Xcode retornará um aviso se você tentar efetuar logoff de um NSInteger como se tivesse um comprimento conhecido. Da mesma forma, você deve ter cuidado ao enviá-los para variáveis ou argumentos digitados como ints, pois você pode perder alguma precisão no processo.
No geral, se você não espera ter centenas de milhares deles na memória de uma só vez, é mais fácil usar o NSInteger do que se preocupar constantemente com a diferença entre os dois.
fonte
No momento (setembro de 2014), eu recomendaria o uso
NSInteger/CGFloat
ao interagir com as APIs do iOS etc. se você também estiver criando seu aplicativo para arm64. Isso é porque você provavelmente irá obter resultados inesperados quando você usa osfloat
,long
eint
tipos.EXEMPLO: FLUTUAÇÃO / DUPLA vs CGFLOAT
Como exemplo, usamos o método delegado UITableView
tableView:heightForRowAtIndexPath:
.Em um aplicativo somente de 32 bits, ele funcionará bem se for escrito assim:
float
é um valor de 32 bits e os 44 que você está retornando são um valor de 32 bits. No entanto, se compilarmos / executarmos o mesmo trecho de código em uma arquitetura arm64 de 64 bits, o 44 será um valor de 64 bits. Retornar um valor de 64 bits quando um valor de 32 bits é esperado fornecerá uma altura de linha inesperada.Você pode resolver esse problema usando o
CGFloat
tipoEsse tipo representa 32 bits
float
em um ambiente de 32 bits e um de 64 bitsdouble
em um ambiente de 64 bits. Portanto, ao usar esse tipo, o método sempre receberá o tipo esperado, independentemente do ambiente de compilação / tempo de execução.O mesmo vale para métodos que esperam números inteiros. Esses métodos esperam um
int
valor de 32 bits em um ambiente de 32 bits e um de 64 bitslong
em um ambiente de 64 bits. Você pode resolver esse caso usando o tipoNSInteger
que serve como umint
ou comlong
base no ambiente de compilação / tempo de execução.fonte
No iOS, atualmente não importa se você usa
int
ouNSInteger
. Será mais importante se / quando o iOS passar para 64 bits.Simplificando,
NSInteger
s sãoint
s no código de 32 bits (e, portanto, 32 bits) elong
s no código de 64 bits (long
s no código de 64 bits têm largura de 64 bits, mas 32 bits no código de 32 bits). O motivo mais provável para usar emNSInteger
vez delong
é não quebrar o código de 32 bits existente (que usaint
s).CGFloat
tem o mesmo problema: em 32 bits (pelo menos no OS X), éfloat
; em 64 bits, édouble
.Atualização: com a introdução do iPhone 5s, iPad Air, iPad Mini com Retina e iOS 7, agora você pode criar código de 64 bits no iOS.
Atualização 2: Além disso, o uso de
NSInteger
s ajuda na interoperabilidade do código Swift.fonte
int = 4 bytes (tamanho fixo independente do arquiteto) NSInteger = depende do tamanho do arquiteto (por exemplo, para arquiteto de 4 bytes = tamanho do NSInteger de 4 bytes)
fonte