Tuesday, January 8, 2013

Массивы в Objective-C. NSArray и NSMutableArray http://idev.by/ios/843/

http://idev.by/ios/843/

Массивы в Objective-C. NSArray и NSMutableArray

АВТОР  
/  /

Массивы в Objective-C

В этой статье мы поговорим о массивах. В Objective-C массивы чаще всего реализуются с помощью классов NSArray и NSMutableArray. Класс NSMutableArray, в отличие от NSArray, позволяет произвольно изменять порядок элементов, создавать и удалять новые элементы.
Для вывода результатов будем использовать функцию NSLog(), с которой мы успели поработать в предыдущей статье про NSString. Консоль можно увидеть внизу окна XCode при запуске приложения. Если консоль не открывается, то выберите пункт меню View->Show Debug Area (⇧⌘Y).

Создание массива

Чтобы создать статичный массив с определенным набором элементов можно использовать следующий код:
  NSArray *array = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", nil];  NSLog(@"%@", array);
Здесь мы создаем массив с тремя элементами. Элементами являются объекты NSString — т.е. простые строки. Также можем воспользоваться методом initWithArray для создания массива из другого массива:
  NSArray *array = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", nil];  NSArray *newArray = [[NSArray alloc] initWithArray:array];  NSLog(@"%@", newArray);
Мы создали полную копию массива. Также мы можем создать массив из другого массива, но использую только часть элементов. Для этого воспользуемся методом subarrayWithRange:
  NSArray *array = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", nil];  NSRange range;  range.length = 2;  range.location = 0;  NSArray *newArray = [array subarrayWithRange:range];  NSLog(@"%@", newArray);
В результате мы получим новый массив, который состоит только из первых двух элементов. В следующем примере мы рассмотрим метод initWithContentsOfFile, который позволяет создать массив из файла:
  NSString *path = [[NSBundle mainBundle] pathForResource:@"filename" ofType:@"txt"];  NSError *error;  NSArray *array = [[NSArray alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];  NSLog(@"%@", array);
Этот метод может показаться вам знакомым по предыдущей статье про строки. Действительно оба класса содержат один и тот же метод, который позволяет создавать объекты с использованием данных, которые могут храниться в файлах. Еще один метод похожий по названию и действию — initWithContentsOfURL, позволяет создать массив использую URL:
  NSString *path = @"http://www.apple.com";  NSArray *array = [[NSArray alloc] initWithContentsOfURL:[NSURL URLWithString:path]];  NSLog(@"%@", array);
Не забудьте указать реальный URL, где будет располагаться ваш файл с данными для массива.

Получение данных из массива

В первую очередь рассмотрим простой и очень важный метод count, который позволяет получить количество элементов в массиве:
  NSArray *array = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", nil];  NSLog(@"%d", [array count]);
Результатом будет «3». Обратите внимание где мы используем этот метод — непосредственно внутри функции NSLog. Далее рассмотрим пример с использование метода objectAtIndex:
  NSArray *array = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", nil];  NSLog(@"%@", [array objectAtIndex:0]);
Этот метод возвращает элемент, который находится на заданном месте. В консоли будет выведен результат «one». Не забывайте что нумерация элементов начинается с нуля.

Поиск элементов в массиве

Самый простой метод поиска элемента в массиве — это containObject:
  NSArray *array = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", nil];  if ([array containsObject:@"one"]) {   NSLog(@"yes");  }  else {   NSLog(@"no");  }
Этот метод возвращает FALSE или TRUE в зависимости от того, присутствует или нет элемент внутри массива. В нашем примере на консоли должно появиться «yes». Далее рассмотрим более функциональные методы indexOfObject и indexOfObject:inRange:
  NSArray *array = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", nil];  NSLog(@"%d", [array indexOfObject:@"two"]);
и
  NSArray *array = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", nil];  NSRange range;  range.length = 2;  range.location = 0;  NSLog(@"%d", [array indexOfObject:@"two"inRange:range]);
Оба метода возвращают номер искомого элемента внутри массива. В первом и во втором примере мы ищем один и тот же элемент «two». Основное отличие заключается в том, что метод indexOfObject:inRange позволяет задать определенный диапазон элементов, где следует проводить поиск.

Сравнение массивов

Простой способ сравнить два массива между собой — использовать метод
  NSArray *array = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", nil];  NSArray *newArray = [[NSArray alloc] initWithObjects:@"one", @"two", nil];  if ([array isEqualToArray:newArray]) {   NSLog(@"yes");  }  else {   NSLog(@"no");  }
В консоли должен появиться результат «no» — наши массивы не идентичны друг другу.

Сортировка массивов

Пожалуй самые интересные методы представлены в этом разделе, так как основная задача массивов хранить большое количество элементов, а также дать возможность выбрать из этого массива необходимые данные. Один из способов добраться до необходимых элементов — сортировка. Так как в процессе сортировки расположение элементов в массиве должно изменяться — в наших примерах мы будем использовать массивы класса NSMutableArray. Самый просто способ отсортировать (например массив состоящий из набора чисел) — это использовать метод sortUsingSelector:
  NSMutableArray *marray = [[NSMutableArray alloc] init];  for (int i = 0 ; i < 10; i++) {   int newElement = random();   [marray addObject:[NSString stringWithFormat:@"%d",newElement]];  }  NSLog(@"%@", marray);  [marray sortUsingSelector:@selector(compare:)];  NSLog(@"%@", marray);
В цикле for мы наполняем массив случайными значениями (значения хранятся в объектах NSString) и выводим значения в консоль. Далее выполняем сортировку с помощью метода sortUsingSelector. В качестве аргумента мы указали @selector(compare:). Это означает что ортировка выполняется с помощью метода compare класса NSString - именно объекты этого класса мы сравниваем между друг другом. Тоже самое можно реализовать с помощью метода sortUsingDescriptors:
  NSMutableArray *marray = [[NSMutableArray alloc] init];  for (int i = 0 ; i < 10; i++) {   int newElement = random();   [marray addObject:[NSString stringWithFormat:@"%d",newElement]];  }  NSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:nil ascending:NO selector:@selector(localizedCompare:)];  NSLog(@"%@", marray);  [marray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];  NSLog(@"%@", marray);
В данном примере мы задаем специальны дескриптор, который описывает процесс сортировки. Обратите внимание на то, что заменив «ascending:NO» на «ascending:YES», мы получим сортировку по убыванию.

Дополнительные возможности NSMutableArray

При создании массивов часто появляется необходимость добавить новый элемент или удалить ненужный. В этом нам помогут массивы NSMutableArray и их методы, которые позволяют модифицировать массивы «на лету». Инициализовать такой массив мы можем методами перечисленными выше а также можем создать массив без каких либо элементов:
  NSMutableArray *marray = [[NSMutableArray alloc] init];
Далее добавляем несколько элементов:
  for (int i = 0 ; i < 5; i++) {   [marray addObject:[NSString stringWithFormat:@"element #%d", i]];  }  NSLog(@"%@", marray);
В консоли мы увидим 5 пронумерованных элементов. Также с помощью метода insertObject:atIndex мы свободно можем добавить элемент в массив в любую позицию:
  [marray insertObject:@"element #X" atIndex:0];  NSLog(@"%@", marray);
В нашем массиве должен появится еще один элемент в самом начале. Еще востребованный способ добавить элементы в массив - использовать элементы другого массива с помощью метода addObjectsFromArray:
  NSArray *array = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", nil];  NSMutableArray *marray = [[NSMutableArray alloc] init];  for (int i = 0 ; i < 5; i++) {   [marray addObject:[NSString stringWithFormat:@"element #%d", i]];  }  [marray insertObject:@"element #X" atIndex:0];  [marray addObjectsFromArray:array];  NSLog(@"%@", marray);
Удалить ненужные элементы можно с помощью нескольких методов. Например - удаляем последний элемент:
  NSMutableArray *marray = [[NSMutableArray alloc] init];  for (int i = 0 ; i < 5; i++) {   [marray addObject:[NSString stringWithFormat:@"element #%d", i]];  }  [marray removeLastObject];  NSLog(@"%@", marray);
На выходе получаем только четыре элемента из пяти добавленных. Свободно можем удалить элемент на любой позиции в массиве:
  [marray removeObjectAtIndex:0];
Какой-либо конкретный элемент:
  [marray removeObject:@"element #1"];
Или все элементы сразу:
  [marray removeAllObjects];
А также элементы в заданном диапазоне:
  NSMutableArray *marray = [[NSMutableArray alloc] init];  for (int i = 0 ; i < 5; i++) {   [marray addObject:[NSString stringWithFormat:@"element #%d", i]];  }  NSRange range;  range.length = 2;  range.location = 2;  [marray removeObjectsInRange:range];  NSLog(@"%@", marray);
Использование массивов в Objective-C дает большие возможности для хранения, записи, удаления и поиска нужных данных. В то же время работа с массивами не требует глубоких знаний в программировании, все методы простые и интуитивно понятные. Более детально с классами NSArray и NSMutableArray вы всегда можете ознакомится в документации.

No comments:

Post a Comment