Fazendo uma matriz de inteiros no iOS

98

Se você quiser fazer uma matriz de inteiros, pode usar NSInteger? Você tem que usar NSNumber? Se sim, então por quê?

neuromancer
fonte
O que você deseja fazer com sua matriz de inteiros?
dreamlax
Não tenho certeza. Acabei de ouvir em algum lugar que você deve usar o NSNumber para matrizes e estava pensando sobre isso.
neuromancer

Respostas:

159

Você pode usar uma matriz C simples e antiga:

NSInteger myIntegers[40];

for (NSInteger i = 0; i < 40; i++)
    myIntegers[i] = i;

// to get one of them
NSLog (@"The 4th integer is: %d", myIntegers[3]);

Ou você pode usar um NSArrayou NSMutableArray, mas aqui você precisará agrupar cada inteiro dentro de uma NSNumberinstância (porque os NSArrayobjetos são projetados para conter instâncias de classe).

NSMutableArray *myIntegers = [NSMutableArray array];

for (NSInteger i = 0; i < 40; i++)
    [myIntegers addObject:[NSNumber numberWithInteger:i]];

// to get one of them
NSLog (@"The 4th integer is: %@", [myIntegers objectAtIndex:3]);

// or
NSLog (@"The 4th integer is: %d", [[myIntegers objectAtIndex:3] integerValue]);
dreamlax
fonte
9
Acho que vale a pena notar que os arrays C são tão complicados para qualquer coisa, exceto o uso único e trivial que, na verdade, é menos problemático embrulhar quaisquer arrays que você planeja manter como NSArrays do NSNumber.
Chuck
2
Sim, e dadas as [presumivelmente] otimizações de nível de especialista sob o capô do NSArray, tenho certeza de que você não sentirá o impacto no desempenho.
dreamlax
@dreamlax Eu me pergunto que tipo de otimização de nível de especialista existe sob o capô do NSArray? Alocação de memória inteligente que simplesmente provavelmente duplica o tamanho da memória alocada quando atinge o limite?
Ben Sinclair
2
@Andy: Dê uma olhada na fonte real do CFArray aqui e verifique os benchmarks aqui . É um pouco mais inteligente do que você pensaria inicialmente.
dreamlax
Supondo que esta matriz seja usada apenas dentro de um método, não há problemas em usar uma matriz C de NSIntegers? Apenas checando ...
Dan Rosenstark
58

Matriz C:

NSInteger array[6] = {1, 2, 3, 4, 5, 6};

Matriz Objective-C:

NSArray *array = @[@1, @2, @3, @4, @5, @6];
// numeric values must in that case be wrapped into NSNumbers

Array Swift:

var array = [1, 2, 3, 4, 5, 6]

Isso também está correto:

var array = Array(1...10)

NB: os arrays são fortemente tipados em Swift; nesse caso, o compilador infere do conteúdo que a matriz é uma matriz de inteiros. Você também pode usar esta sintaxe de tipo explícito:

var array: [Int] = [1, 2, 3, 4, 5, 6]

Se você quisesse uma variedade de Doubles, você usaria:

var array = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0] // implicit type-inference

ou:

var array: [Double] = [1, 2, 3, 4, 5, 6] // explicit type
Frédéric Adda
fonte
1
Qual seria a sintaxe "@number" equivalente para um inteiro negativo?
Ziofil
5

Se você quiser usar um NSArray, precisará de uma classe Objective-C para colocá-lo - daí o requisito NSNumber.

Dito isso, Obj-C ainda é C, então você pode usar arrays C regulares e manter ints regulares em vez de NSNumbers, se necessário.

Dennis Munsie
fonte
4

Você pode usar CFArray em vez de NSArray. Aqui está um artigo explicando como.

CFMutableArrayRef ar = CFArrayCreateMutable(NULL, 0, NULL);
for (NSUInteger i = 0; i < 1000; i++)
{
  CFArrayAppendValue(ar, (void*)i);
}
CFRelease(ar); /* Releasing the array */

O mesmo se aplica à versão CoreFoundation dos outros contêineres.

coyotte508
fonte
3
Se há uma vantagem de usar CFArray em vez de NSArray, não vejo isso. Um NSArray É um CFArray sob o capô; isso é apenas fazer da maneira mais difícil.
David Gish
1
@Cryptognome há uma pequena diferença aqui, o CFArray não retém ou libera nada porque foi criado sem callbacks. Eu concordo, porém, não parece haver nenhuma vantagem.
dreamlax
3

Se a ordem dos seus inteiros não for necessária e se houver apenas valores únicos

você também pode usar NSIndexSet ou NSMutableIndexSet Você será capaz de adicionar e remover inteiros facilmente ou verificar se sua matriz contém um inteiro com

- (void)addIndex:(NSUInteger)index
- (void)removeIndex:(NSUInteger)index
- (BOOL)containsIndexes:(NSIndexSet *)indexSet

Verifique a documentação para mais informações.

didier_v_
fonte
2
É uma péssima ideia. Aqui está um trecho da documentação da Apple: Você não deve usar conjuntos de índices para armazenar uma coleção arbitrária de valores inteiros porque os conjuntos de índices armazenam índices como intervalos classificados. Isso os torna mais eficientes do que armazenar uma coleção de inteiros individuais. Isso também significa que cada valor de índice pode aparecer apenas uma vez no conjunto de índices.
Rudolf Adamkovič
1
Concordo e é por isso que comecei minha resposta com um aviso. No entanto, conheço algumas pessoas que fizeram essa pergunta sobre matrizes de inteiros e realmente precisavam de um conjunto de índices. É por isso que dei esta resposta alternativa.
didier_v_
O que há de errado com apenas um regular NSSet(e usar inteiros dentro de um NSNumber)?
dreamlax de
@dreamlax overhead, mas de modo geral, as pessoas que fazem essas perguntas não podem lidar com C e simplesmente têm poucos números para armazenar, então NSArray ou NSSet deve ser o melhor.
Ben Sinclair
2

Acho que é muito mais fácil usar o NSNumbers. Tudo o que você precisa fazer:

NSNumber *myNum1 = [NSNumber numberWithInt:myNsIntValue1];
NSNumber *myNum2 = [NSNumber numberWithInt:myNsIntValue2];
.
.
.
NSArray *myArray = [NSArray arrayWithObjects: myNum1, myNum2, ..., nil];
Neeku
fonte
mas e se sua matriz tiver 10 ou 100 números?
Henson
1
Você pode usar forou apenas outra matriz para os números e, em seguida arrayWithArray.
Neeku