Objective-C Language
NSArray
Поиск…
Синтаксис
- NSArray * слова; // Объявление неизменяемого массива
- NSMutableArray * слова; // Объявление изменяемого массива
- NSArray * words = [NSArray arrayWithObjects: @ "one", @ "two", nil]; // Синтаксис инициализации массива
- NSArray * words = @ [@ "list", @ "of", @ "words", @ 123, @ 3.14]; // Объявление массивных литералов
- NSArray * stringArray = [NSArray arrayWithObjects: [NSMutableArray array], [NSMutableArray array], [NSMutableArray array], nil]; // Создание многомерных массивов
Создание массивов
Создание неизменяемых массивов:
NSArray *myColors = [NSArray arrayWithObjects: @"Red", @"Green", @"Blue", @"Yellow", nil];
// Using the array literal syntax:
NSArray *myColors = @[@"Red", @"Green", @"Blue", @"Yellow"];
Для изменяемых массивов см. NSMutableArray .
Определение количества элементов в массиве
NSArray *myColors = [NSArray arrayWithObjects: @"Red", @"Green", @"Blue", @"Yellow", nil];
NSLog (@"Number of elements in array = %lu", [myColors count]);
Доступ к элементам
NSArray *myColors = @[@"Red", @"Green", @"Blue", @"Yellow"];
// Preceding is the preferred equivalent to [NSArray arrayWithObjects:...]
Получение отдельного элемента
Метод objectAtIndex:
обеспечивает единый объект. Первым объектом в NSArray
является индекс 0. Поскольку NSArray
может быть однородным (содержать разные типы объектов), возвращаемый тип - id
(«любой объект»). ( id
может быть назначен переменной любого другого типа объекта.) Важно, что NSArray
s может содержать только объекты. Они не могут содержать такие значения, как int
.
NSUInteger idx = 2;
NSString *color = [myColors objectAtIndex:idx];
// color now points to the string @"Green"
Clang обеспечивает лучший синтаксис подстроки как часть его функций литералов массива :
NSString *color = myColors[idx];
Оба они вызывают исключение, если прошедший индекс меньше 0 или больше, чем count - 1
.
Первый и последний элемент
NSString *firstColor = myColors.firstObject;
NSString *lastColor = myColors.lastObject;
firstObject
и lastObject
являются вычисленными свойствами и возвращают nil
а не сбой для пустых массивов. Для одноэлементных массивов они возвращают один и тот же объект. Хотя метод firstObject
не был представлен NSArray
до iOS 4.0.
NSArray *empty = @[]
id notAnObject = empty.firstObject; // Returns `nil`
id kaboom = empty[0]; // Crashes; index out of bounds
Фильтрация массивов с помощью предикатов
NSArray *array = [NSArray arrayWithObjects:@"Nick", @"Ben", @"Adam", @"Melissa", nil];
NSPredicate *aPredicate = [NSPredicate predicateWithFormat:@"SELF beginswith[c] 'a'"];
NSArray *beginWithA = [array filteredArrayUsingPredicate:bPredicate];
// beginWithA contains { @"Adam" }.
NSPredicate *ePredicate = [NSPredicate predicateWithFormat:@"SELF contains[c] 'e'"];
[array filterUsingPredicate:ePredicate];
// array now contains { @"Ben", @"Melissa" }
Больше о
Apple doc: NSPredicate
Преобразование NSArray в NSMutableArray для модификации
NSArray *myColors = [NSArray arrayWithObjects: @"Red", @"Green", @"Blue", @"Yellow", nil];
// Convert myColors to mutable
NSMutableArray *myColorsMutable = [myColors mutableCopy];
Сортировка массива с настраиваемыми объектами
Метод сравнения
Либо вы реализуете метод сравнения для своего объекта:
- (NSComparisonResult)compare:(Person *)otherObject {
return [self.birthDate compare:otherObject.birthDate];
}
NSArray *sortedArray = [drinkDetails sortedArrayUsingSelector:@selector(compare:)];
NSSortDescriptor
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"birthDate"
ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray = [drinkDetails sortedArrayUsingDescriptors:sortDescriptors];
Вы можете легко отсортировать несколько ключей, добавив в массив несколько. Также возможно использование пользовательских методов-компараторов. Посмотрите документацию .
Блоки
NSArray *sortedArray;
sortedArray = [drinkDetails sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSDate *first = [(Person*)a birthDate];
NSDate *second = [(Person*)b birthDate];
return [first compare:second];
}];
Спектакль
-compare:
и block-based будут в целом более NSSortDescriptor
, чем использование NSSortDescriptor
поскольку последний полагается на KVC. Основное преимущество метода NSSortDescriptor
заключается в том, что он предоставляет способ определения вашего порядка сортировки с использованием данных, а не кода, что упрощает, например, настраивать вещи, чтобы пользователи могли сортировать NSTableView
, щелкая по строке заголовка.
Преобразование между наборами и массивами
NSSet *set = [NSSet set];
NSArray *array = [NSArray array];
NSArray *fromSet = [set allObjects];
NSSet *fromArray = [NSSet setWithArray:array];
Обратный массив
NSArray *reversedArray = [myArray.reverseObjectEnumerator allObjects];
Проникновение через
NSArray *myColors = @[@"Red", @"Green", @"Blue", @"Yellow"];
// Fast enumeration
// myColors cannot be modified inside the loop
for (NSString *color in myColors) {
NSLog(@"Element %@", color);
}
// Using indices
for (NSUInteger i = 0; i < myColors.count; i++) {
NSLog(@"Element %d = %@", i, myColors[i]);
}
// Using block enumeration
[myColors enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL * stop) {
NSLog(@"Element %d = %@", idx, obj);
// To abort use:
*stop = YES
}];
// Using block enumeration with options
[myColors enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id obj, NSUInteger idx, BOOL * stop) {
NSLog(@"Element %d = %@", idx, obj);
}];
Использование дженериков
Для дополнительной безопасности мы можем определить тип объекта, который содержит массив:
NSArray<NSString *> *colors = @[@"Red", @"Green", @"Blue", @"Yellow"];
NSMutableArray<NSString *> *myColors = [NSMutableArray arrayWithArray:colors];
[myColors addObject:@"Orange"]; // OK
[myColors addObject:[UIColor purpleColor]]; // "Incompatible pointer type" warning
Следует отметить, что это проверяется только во время компиляции.
Перечисление с использованием блоков
NSArray *myColors = @[@"Red", @"Green", @"Blue", @"Yellow"];
[myColors enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSLog(@"enumerating object %@ at index %lu", obj, idx);
}];
Установив параметр stop
на « YES
вы можете указать, что дальнейшее перечисление не требуется. для этого просто установите &stop = YES
.
NSEnumerationOptions
Вы можете перечислить массив в обратном порядке и / или одновременно:
[myColors enumerateObjectsWithOptions:NSEnumerationConcurrent | NSEnumerationReverse
usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSLog(@"enumerating object %@ at index %lu", obj, idx);
}];
Перечисление подмножества массива
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(1, 1)];
[myColors enumerateObjectsAtIndexes:indexSet
options:kNilOptions
usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSLog(@"enumerating object %@ at index %lu", obj, idx);
}];
Сравнение массивов
Массивы можно сравнить для равенства с метко названным isEqualToArray: method, который возвращает YES, когда оба массива имеют одинаковое количество элементов, и каждая пара передает isEqual: сравнение.
NSArray *germanMakes = @[@"Mercedes-Benz", @"BMW", @"Porsche",
@"Opel", @"Volkswagen", @"Audi"];
NSArray *sameGermanMakes = [NSArray arrayWithObjects:@"Mercedes-Benz",
@"BMW", @"Porsche", @"Opel",
@"Volkswagen", @"Audi", nil];
if ([germanMakes isEqualToArray:sameGermanMakes]) {
NSLog(@"Oh good, literal arrays are the same as NSArrays");
}
Важно то, что каждая пара должна пройти тест isEqual:. Для пользовательских объектов этот метод должен быть реализован. Он существует в протоколе NSObject.
Добавить объекты в NSArray
NSArray *a = @[@1];
a = [a arrayByAddingObject:@2];
a = [a arrayByAddingObjectsFromArray:@[@3, @4, @5]];
Эти методы оптимизированы для быстрого создания нового массива, обычно без необходимости уничтожать исходный массив или даже выделять больше памяти.