Создание массива целых чисел в iOS

99

Если вы хотите создать массив целых чисел, можете ли вы использовать NSInteger? Вам нужно использовать NSNumber? Если да, то почему?

нейромант
источник

Ответы:

159

Вы можете использовать простой старый массив C:

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]);

Или вы можете использовать NSArrayили NSMutableArray, но здесь вам нужно будет заключить каждое целое число внутри NSNumberэкземпляра (поскольку NSArrayобъекты предназначены для хранения экземпляров класса).

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]);
мечта
источник
9
Я думаю, стоит отметить, что массивы C доставляют столько хлопот для чего угодно, кроме тривиального, одноразового использования, что на самом деле легче обернуть любые массивы, которые вы планируете хранить как NSArrays NSNumber.
Чак
2
Да, и, учитывая [предположительно] оптимизацию на уровне экспертов NSArray, я уверен, что вы не почувствуете падения производительности.
dreamlax
@dreamlax. Интересно, какая оптимизация на уровне эксперта скрывается за NSArray? Интеллектуальное распределение памяти, которое, вероятно, просто удваивает размер выделенной памяти, когда она достигает предела? :) p
Бен Синклер
2
@Andy: Взгляните на фактический источник CFArray здесь и проверьте тесты здесь . Это немного умнее, чем вы думаете.
dreamlax
Предполагая, что этот массив просто используется в методе, нет проблем с использованием массива C NSIntegers? Просто двойная проверка ...
Дэн Розенстарк,
58

Массив C:

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

Массив Objective-C:

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

Быстрый массив:

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

Это тоже правильно:

var array = Array(1...10)

NB: массивы строго типизированы в Swift; в этом случае компилятор делает вывод из содержимого, что массив является массивом целых чисел. Вы также можете использовать этот синтаксис явного типа:

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

Если вам нужен массив Double, вы должны использовать:

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

или:

var array: [Double] = [1, 2, 3, 4, 5, 6] // explicit type
Фредерик Адда
источник
1
Каким будет синтаксис "@number" для отрицательного целого числа?
Ziofil 06
5

Если вы хотите использовать NSArray, вам понадобится класс Objective-C, чтобы поместить в него - отсюда требование NSNumber.

Тем не менее, Obj-C по-прежнему является C, поэтому вы можете использовать обычные массивы C и хранить обычные int вместо NSNumbers, если вам нужно.

Деннис Манси
источник
5

Вы можете использовать CFArray вместо NSArray. Вот статья, объясняющая, как это сделать.

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

То же самое относится и к версии CoreFoundation других контейнеров.

койот508
источник
3
Если есть преимущество использования CFArray перед NSArray, я этого не вижу. NSArray - это CFArray под капотом; это просто трудный путь.
Дэвид Гиш
1
@Cryptognome здесь есть небольшая разница, CFArray ничего не сохраняет и не выпускает, потому что он был создан без обратных вызовов. Я согласен, но, кажется, нет никаких преимуществ.
dreamlax
4

Я создал простую оболочку Objective C вокруг старого доброго массива C для более удобного использования: https://gist.github.com/4705733

MrTJ
источник
3

Если порядок ваших целых чисел не требуется, и если есть только уникальные значения

вы также можете использовать NSIndexSet или NSMutableIndexSet. Вы сможете легко добавлять и удалять целые числа или проверять, содержит ли ваш массив целое число с

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

Проверьте документацию для получения дополнительной информации.

didier_v_
источник
2
Это ужасная идея. Вот отрывок из документации Apple: вы не должны использовать наборы индексов для хранения произвольной коллекции целочисленных значений, потому что индекс устанавливает индексы хранилища как отсортированные диапазоны. Это делает их более эффективными, чем хранение коллекции отдельных целых чисел. Это также означает, что каждое значение индекса может появляться в наборе индексов только один раз.
Рудольф Адамкович 01
1
Я согласен и поэтому начал свой ответ с предупреждения. Однако я знаю некоторых людей, которые задавали этот вопрос о целочисленных массивах и действительно нуждались в индексном наборе. Вот почему я дал альтернативный ответ.
didier_v_ 04
Что не так с обычным NSSet(и с использованием целых чисел, заключенных в NSNumber)?
dreamlax
@dreamlax накладные расходы, но, вообще говоря, люди, задающие такие вопросы, не могут обрабатывать C, и у них просто есть несколько номеров для хранения, поэтому NSArray или NSSet должны быть лучшими.
Бен Синклер
2

Я думаю, что использовать NSNumbers намного проще. Это все, что вам нужно сделать:

NSNumber *myNum1 = [NSNumber numberWithInt:myNsIntValue1];
NSNumber *myNum2 = [NSNumber numberWithInt:myNsIntValue2];
.
.
.
NSArray *myArray = [NSArray arrayWithObjects: myNum1, myNum2, ..., nil];
Neeku
источник
но что, если в вашем массиве 10 или 100 чисел?
Henson
1
Вы можете использовать forили просто другой массив для чисел, а затем arrayWithArray.
Neeku