ПРОГРАММИРОВАНИЕ ПОД IPHONE, IPAD OBJECTIVE-C Часть 1

NSArray (массивы)

Иногда вам необходимо работать с наборами данных. Например, у вас есть список строк. Было бы довольно обременительно оперировать с ним, используя переменную для каждой из строк. Конечно же есть более подходящее решение — это массивы.

Массив — это упорядоченный список объектов (если быть более точным, список указателей на объекты). Вы можете добавлять объекты в массив, удалять их, запрашивать объекты по индексу. Также вы можете узнать сколько элементов содержит массив.

Когда вы считаете, обычно начинаете с единицы. Однако, в массивах, первый элемент является нулевым, второй элемент имеет индекс 1 и так далее.

Чтобы рассмотреть подробнее работу массивов давайте создадим новый проект на основе представления (View-based Application) и назовем его Arrays. Теперь откройте файл ArraysViewController.m, раскомментируйте в нем метод viewDidLoad и добавьте в него несколько строк:

<code data-result="[object Object]">NSArray *a1 = [NSArray array];
NSArray *a2 = [NSArray arrayWithArray:a1];
NSArray *a3 = [NSArray arrayWithObject:@"An object"];</code>

В первой строке мы создаем пустой массив. Вторая строка демонстрирует метод создания массива на основании уже имеющегося массива. В третьей строке мы создаем массив с одним объектом @»An object».

Следующий пример демонстрирует возможность хранения в массиве объекты совершенно разных типов:

<code data-result="[object Object]">NSDate *aDate = [NSDate date];
NSNumber *aNamber = [NSNumber numberWithInt:10];
NSString *aString = @"Bill";

NSArray *aArray = [NSArray arrayWithObjects:aDate, aNamber, aString, nil];
NSLog(@"%@",aArray);</code>

В этом примере следует обратить внимание на слове nil в объявлении массива. Этим символом мы даем знать компилятору, что массив окончен.

В первых трех строках мы создаем объекты, которые, как я уже говорил, относятся к разным типам (об этих типах я расскажу позже). Затем мы создаем массив с этих объектов и выводим наш массив в консоль. А вот и результат работы этой части кода:

2011-03-17 23:27:36.651 Arrays[6019:207] (

    «2011-03-17 21:27:36 +0000»,

    10,

    Bill

)

В следующем примере мы рассмотрим сразу несколько методов класса NSArray.

<code data-result="[object Object]">NSArray *students = [NSArray arrayWithObjects:@"Tom", @"Bill", @"Joe", nil];    
BOOL containts = [students containsObject:@"Bill"];
NSInteger count = [students count];
id obj = [students lastObject];
id obj1 = [students objectAtIndex:1];

NSString *results = [NSString stringWithFormat:
                     @" students contain Bill? %i"
                     @" number of students is %i"
                     @" last object: %@"
                     @" object at index 1 is %@",
                     containts, count, obj, obj1];
NSLog(@"%@", results);</code>

Сначала мы создаем массив с трех строк. Метод containsObject возвращает нам истину, если параметр, который мы в него передали (строка @»Bill») содержится в массиве. Метод count возвращает нам количество элементов массива (размер массива). МетодlastObject возвращает последний объект, а objectAtIndex объект по номеру, который мы передали в качестве параметра этого метода (не стоит забывать, что нумерация начинается с нуля). Я предположил, что мы не знаем тип объектов, которые содержит массив, поэтому в качестве типа указал id. Затем мы формируем с результаты этих методов мы храним в переменных. Затем мы формируем с этих переменных строку и выводим ее в консоль.

Следующий код поможет нам узнать индекс объекта, который содержится в массиве.

<code data-result="[object Object]">NSInteger location = [students indexOfObject:@"Joe"];
NSLog(@"Location of Joe is %i", location);</code>

Любопытно, что следующий метод для поиска объекта использует сравнение не значения, а адреса объекта в памяти.

<code data-result="[object Object]">NSString *joe1 = @"Joe";
NSString *joe2 = [NSString stringWithFormat:@"%@", @"Joe"];
NSString *joe3 = [NSString stringWithFormat:@"%@", @"Joe"];

NSArray *a = [NSArray arrayWithObjects:joe1, joe2, joe3, nil];
NSInteger location1 = [a indexOfObjectIdenticalTo:joe2];
NSLog(@"%i", location1);</code>

Результатом работы этого кода будет значение 2 (значения переменных joe одинаковые, но их адреса в памяти — разные).

Давайте рассмотрим как сравнивать массивы.

<code data-result="[object Object]">NSArray *students2 = [NSArray arrayWithObjects:@"Tom", @"Bill", @"Joe", nil];
BOOL equal = [students2 isEqualToArray:students];
NSLog(@"Arrays equal? %i", equal);</code>

Если массивы равны — значение equal будет равно YES, иначе — NO.

Следующий пример формирует строку с элементов массива.

<code data-result="[object Object]">NSString *joined = [students componentsJoinedByString:@", "];
NSLog(@"%@", joined);</code>

В качестве параметра этого метода мы передаем значение разделителя, этим разделителем в созданной строке элементы будут отделяться друг от друга.

Наверное одним из самых важных свойств массива — это его возможность сортировки. В следующем методе демонстрируется эта возможность. Для начала нам следует добавить функцию, которая будет выполнять функцию сортировки:

<code data-result="[object Object]">NSInteger alphabeticSort(id string1, id string2, void *reverse)
{
    if (reverse) {
        return [string2 localizedCaseInsensitiveCompare:string1];
    } else {
        return [string1 localizedCaseInsensitiveCompare:string2];
    }
}</code>

Да, вы не ошиблись это код С. Это как раз тот случай, когда вам пригодятся та информация, которую я описывал еще в первых статьях… Затем следует сам метод, который возвращает нам отсортированный массив:

<code data-result="[object Object]">BOOL reverseSort = YES;
NSArray *sortedArray = [students sortedArrayUsingFunction:alphabeticSort context:(void*)reverseSort];
NSLog(@"Sort using function:"YES" %@", sortedArray);</code>

Напоследок хотелось бы продемонстрировать методе отбора. Это очень полезный метод, он напоминает работу SQL запросов, о которых я напишу позже.

<code data-result="[object Object]">NSArray *students3 = [NSArray arrayWithObjects:@"Tom", @"Bill", @"Tom", @"Joe", @"Tom", nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains[cd] %@", @"Tom"];
NSArray *aTom = [students3 filteredArrayUsingPredicate:predicate];
NSLog(@"%@", aTom);</code>

В этом примере мы создали массив, в котором три раза встречается имя Tom. Затем мы создаем экземпляр predicate классаNSPredicate. Это похоже на создание строки stringWithFormat, дело в том, что эта строка имеет специфический синтаксис. Как раз пример этого синтаксиса и приведен в коде выше. В результате мы получим новый массив, который будет состоять только из объектов равных значению @»Tom».

Важным моментом в этом методе есть случай, если ваш массив содержит словари (NSDictionary). В таком случае синтаксис строки для создания предиката будет иметь следующий вид: @»SELF.key == %@» , @»Tom»key — это значение ключа словаря.
Исходный код можно скачать здесь.

Comments are closed.