Чтение онлайн

ЖАНРЫ

Программирование на Objective-C 2.0
Шрифт:

Набор, или множество (set) — это коллекция уникальных объектов. Набор может быть мутабельным или немутабельным. Для наборов можно выполнять операции поиска, добавления и удаления членов (мутабельные наборы), сравнения, поиск пересечения (intersect) и объединения (union).

Для работы с наборами в программе нужно включить следующую строку. #import <Foundation/NSSet.h>

В программе 15.16 показаны основные операции с наборами. Предположим, что нам нужно выводить содержимое наборов во время выполнения программы. Создаем новый метод с именем print и добавляем метод print в класс NSSet, создавая новую категорию с именем Printing. NSMutableSet — это подкласс NSSet, поэтому мутабельные наборы тоже могут использовать новый метод print. #import <Foundation/NSObject.h> #import <Foundation/NSSet.h> #import <Foundation/NSValue.h> #import <Foundation/NSAutoreleasePool.h> #import <Foundation/NSString.h> //

Создание объекта целого типа #define INTOBJ(v) [NSNumber numberWithlnteger: v] // Добавление в NSSet метода print с помощью категории Printing @interface NSSet (Printing) -(void) print; @end @implementation NSSet (Printing) -(void) print { printf ("{"); for (NSNumber *element in self) printf (" %li", (long) [element integerValue]); printf ("}\n"); } @end int main (int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSMutableSet *set1 = [NSMutableSet setWithObjects: INTOBJ(I), INT0BJ(3), INTOBJ(5), INTOBJ(IO), nil]; NSSet *set2 = [NSSet setWithObjects: INTOBJ(-5), INTOBJ(IOO), INTOBJ(3), INT0BJ(5), nil]; NSSet *set3 = [NSSet setWithObjects: INT0BJ( 12), 1NTOBJ(200), INT0BJ(3), nil]; NSLog (@"set1:"); [set1 print]; NSLog (<®"set2:"); [set2 print]; // Проверка на равенство if ([set 1 isEqualToSet: set2] == YES) NSLog (@"set1 equals set2n); else NSLog (@"set1 is not equal lo set2"); // Проверка членства в наборе if ([set1 containsObject: INTOBJ(IO)] == YES) NSLog (@"set1 contains 10"); else NSLog (@"setl does not contain 10"); if ([set2 containsObject: INTOBJ(10)] == YES) NSLog (@"set2 contains 10"); else NSLog (@"set2 does not contain 10"); // Добавление и удаление объектов из мутабельного набора setl [setl addObject: INTOBJ(4)]; [setl removeObject: INTOBJ(IO)]; NSLog (@"set1 after adding 4 and removing 10:"); [setl print]; // Получение пересечения двух наборов [setl intersectSet: set2]; NSLog (@"set1 intersect set2:"); [setl print]; // Объединение двух наборов [set1 unionSet:set3]; NSLog (@"set1 union set3:"); [set1 print]; [pool drain]; return 0; }

Вывод программы 15.16 set1: (набор 1) (3 10 1 5} set2: (набор 2) { 100 3-55} set1 is not equal to set2 (set1 не равен набору set2| set1 contains 10 (set1 содержит 10) set2 does not contain 10 (set2 не содержит 10) set1 after adding 4 and removing 10: (set1 после добавления 4 и удаления 10) { 3 1 5 4 } set1 intersect set2: (пересечение set1 c set2) { 3 5 } set1 union set3: {объединение setl c set3) { 12 3 5 200}

В методе print используется описанный ранее метод быстрого перечисления для считывания каждого элемента из набора и определяется макрос с именем INTOBJ для создания объекта из целого значения. Это позволяет сделать про-грамму короче и исключить необязательный ввод. Конечно, наш метод print не является достаточно обобщенным, поскольку он работает только с наборами, содержащими целые элементы. Но это хороший пример, напоминающий, как добавлять методы в класс с помощью категорий. (Отметим, что в методе print используется процедура printf библиотеки С для вывода элементов каждого на-бора в одной строке.)

Метод setWithObjects: создает новый набор из списка объектов, заканчиваю-щегося объектом nil. После создания трех наборов программа выводит первые два набора с помощью нового метода print. Затем метод isEqualToSet проверяет равенство набора setl набору set2 (они не равны).

Метод containsObject: проверяет сначала, содержится ли целый элемент 10 в наборе setl, и затем делает то же самое для набора set2. Булевы значения, воз-вращаемые этим методом, показывают, что данный элемент содержится в первом наборе и не содержится во втором.

Затем в программе используются методы addObject: и removeObject:, чтобы добавить 4 и удалить 10 из setl. Вывод содержимого этого набора показывает, что операции выполнены успешно.

Методы intersect: и union: используются, чтобы вычислять пересечение и объединение двух наборов. В обоих случаях результат операции заменяет получателя сообщения.

В Foundation framework имеется также класс NSCountedSet. Наборы могут содержать более одного экземпляра одного и того же объекта, однако вместо не-скольких представлений этого объекта в наборе поддерживается счетчик эк-земпляров. При первом добавлении объекта в набор его счетчик равен 1. При последующем добавлении этого объекта в набор происходит наращивание его счетчика, а при удалении объекта счетчик уменьшается на 1. Когда счетчик ста-новится равным 0, объект удаляется из набора. Метод countForObject: читает счет-чик для указанного объекта в наборе.

Наборы со счетчиками могут применяться, например, в приложении

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

Мы только что показали некоторые основные операции с наборами. В таб-лицах 15.8 и 15.9 приводятся наиболее распространенные методы для работы с мутабельными и немутабсльными наборами. Поскольку NSMutableSet является подклассом класса NSSet, он наследует его методы.

В таблицах 15.8 и 15.9 obj, objt и obj2являются произвольными объектами, nsset — это объект класса NSSet или NSMutableSet, size — целый элемент типа NSUInteger.

Табл. 15.8. Наиболее распространенные методы класса NSSet Метод Описание +(id) setWithObjects: obj1, obj2, ..., nil Создает новый набор из списка объектов. -(id) imtWithObjects: obj1, obj2, ..., nil Инициализирует новый выделенный (alloc) набор со списком объектов. -(NSUInteger) count Возвращает число членов данного набора. -(BOOL) containsObject: obj Определяет, содержится ли obj в данном наборе. -(BOOL) member: obj Определяет, содержится ли оbj в данном наборе (с использованием метода isEqual:). -(NSEnumerator *) objectEnumerator Возвращает объект класса NSEnumerator для всех объектов набора. -(BOOL) isSubsetOfSet: nsset Определяет, содержится ли каждый член получателя в nsset. -(BOOL) intersectsSet: nsset Определяет, содержится ли хотя бы один член получателя в nsset. -(BOOL) isEqualToSet: nsset Проверяет равенство двух наборов.

Табл. 15.9. Наиболее распространенные методы класса NSMutableSet Метод Описание– (id) setWithCapacity: size Создает новый набор с начальной емкостью для хранения size членов. -(id) initWithCapacity: size Задает начальную емкость нового выделенного (alloc) набора для size членов. -(void) addObject: obj Добавляет obj в набор. -(void) removeObject: obj Удаляет obj из набора. -(void) removeAllObjects Удаляет всех членов набора-получателя. -(void) unionSet: nsset Добавляет каждого члена nsset в набор-получатель. -(void) minusSet: nsset Удаляет всех членов nsset из набора-получателя. -(void) intersectSet: nsset Удаляет из набора-получателя всех членов, не входящих в nsset. Упражнения

Найдите класс NSCalendarDate в своей документации. Добавьте в NSCalendarOate новую категорию с именем BapsedDays. В этой категории добавьте метод в соответствии со следующим объявлением этого метода.
– (unsigned long) numberOfEiapsedDays: (NSCalendarDate *} theDate; Этот метод должен возвращать число дней (elapsed days), прошедших между датой получателя и датой аргумента. Напишите тестовую пробам му для проверки этого метода. (Подсказка: посмотрите метод years:months:days:hours:minutes:seconds:sinceDate:.)

Внесите изменения в метод lookup:, разработанный в этой главе для класса AddressBook, чтобы можно было проверять частичное совпадение с именем. Выражение с сообщением | my Book lookup: @»steve»] должно определять соответствие записи, содержащей строку Steve в любой части имени.

Внесите изменения в метод lookup:, разработанный в этой главе для класса AddressBook, чтобы можно было искать все соответствия в адресной книге. Этот метод должен возвращать массив, содержащий все соответствующие адресные, карточки, или nil, если не найдено ни одного соответствия.

Добавьте новые поля по вашему выбору в класс AddressCard. Например, вы можете разделить поле name на поля имени и фамилии, а также добавить адрес (с полями штата, города, почтового кода и страны) и номер телефона. Напишите метод-установщик и метод-получатель, а также проследите, чтобы методы print и list правильно выводили поля.

После завершения упражнения 3 внесите изменения в метод lookup: из уп-ражнения 2, чтобы выполнять поиск по всем полям адресной карточки. Как вы спроектировал и бы свои классы AddressCard и AddressBook, чтобы в AddressBook не нужно было знать все поля, хранящиеся в AddressCard?

Добавьте метод removeName: в класс AddressBook, чтобы удалять запись адресной книги в соответствии со следующим объявлением этого метода. -(BOOL) removeName: (NSString *) theName; Используйте метод lookup:, разработанный в упражнении 2. Если имя не най-дено или существует несколько записей, метод должен возвращать значение N0. Если запись успешно удалена, метод должен возвращать значение YES.

Используя класс Fraction, определенный в части 1, создайте массив дробей (fraction) с некоторыми произвольными значениями. Затем напишите код для вычисления суммы всех дробей, хранящихся в этом массиве.

Поделиться с друзьями: