355 500 произведений, 25 200 авторов.

Электронная библиотека книг » Стивен Кочан » Программирование на Objective-C 2.0 » Текст книги (страница 20)
Программирование на Objective-C 2.0
  • Текст добавлен: 19 сентября 2016, 13:02

Текст книги "Программирование на Objective-C 2.0"


Автор книги: Стивен Кочан



сообщить о нарушении

Текущая страница: 20 (всего у книги 32 страниц)

Вывод программы 15.10 Entries in address book after creation: 0 (Записей в адресной книге после создания) Entries in address book after adding cards: 4 (Записей в адресной книге после добавления карточек) ======== Contents of: Linda’s Address Book == Julia Kochan [email protected] Tony lannino [email protected] Stephen Kochan [email protected] Jamie Baker [email protected]

В программе задаются четыре адресные карточки и создается новая адресная книга с именем Linda’s Address Book. Эти четыре карточки добавляются затем в адресную книгу с помощью метода addCard:, после чего метод list выводит и проверяет содержимое адресной книги. Поиск в адресной книге

Если адресная книга большая, то вы не будете выводить все ее содержимое каж-дый раз, чтобы найти конкретного человека. Добавим для этого соответствующий метод. Назовем этот метод lookup: (поиск); он будет принимать в качестве аргумента имя, которое нужно найти. Этот метод будет выполнять поиск соот-ветствия в адресной книге (без учета регистра букв) и возвращать соответству-ющую запись, если она найдена. Если указанного имени нет в адресной книге, возвращается nil.

Ниже приводится метод lookup:. // поиск адресной карточки по имени – требуется точное совпадение -(AddressCard *) lookup: (NSString *) theName {  for (AddressCard *nextCard in book ) if ([[nextCard name] caselnsensitiveCompare: theName] == NSOrderedSame ) return nextCard; return nil; }

Поместим объявление этого метода в файл секции interface, а его определение – в файл секции implementation и напишем тестовую программу для опробования этого метода. Это программа 15.11 и ее вывод. #import "AddressBook.h" #import int main (int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSString *aName = @ "Julia Kochan"; NSString *aEmail = @"[email protected]"; NSString *bName = @"Tony lannino"; NSString *bEmail = @"[email protected]"; NSString *cName = @"Stephen Kochan"; NSString *cEmail = @"[email protected]"; NSString *dName = Jamie Baker"; NSString *dEmail = @"[email protected]"; AddressCard *card1 = [[AddressCard alloc] init]; AddressCard *card2 = [[AddressCard alloc] init]; AddressCard *card3 = [[AddressCard alloc] init]; AddressCard *card4 = [[AddressCard alloc] init]; AddressBook *myBook = [AddressBook alloc]; AddressCard *myCard; // Сначала задаем четыре адресные карточки [card 1 setName: aName andEmail: aEmail]; [card2 setName: bName andEmail: bEmail]; [card3 setName: cName andEmail: cEmail]; [card4 setName: dName andEmail: dEmail]; myBook = [myBook initWithName: @"Linda’s Address Book"]; // Добавляем несколько карточек в адресную книгу [myBook addCard: card 1]; [myBook addCard: card2];  [myBook addCard: card3]; [myBook addCard: card4]; // ПОИСК человека по имени NSLog (@"Lookup: Stephen Kochan"); myCard = [myBook lookup: @"stephen kochan"]; if (myCard != nil) [myCard print]; else NSLog (@"Not found!"); // Еще одна попытка поиска NSLog (@"Lookup: Haibo Zhang"); myCard = [myBook lookup: @"Haibo Zhang"]; if (myCard != nil) [myCard print]; else NSLog (@"Not found!"); [cardl release]; [card2 release]; [card3 release]; [card4 release]; [myBook release]; [pool drain]; return 0; }

Вывод программы 15.11 Lookup: Stephen Kochan (Найти:) =============================== | | | Stephen Kochan | | [email protected] | | | | | | | | 0 0 | =============================== Lookup: Haibo Zhang (Поиск:) Not found! (He найден!)

Когда метод lookup: нашел в адресной книге имя Stephen Kochan (совпадение без учета регистра букв), этот метод передал результирующую адресную карточку методу AddressCard print для ее вывода. При второй попытке поиска имя Haibo Zhang не было найдено.

Этот слишком простой метод поиска, поскольку он требует точного совпаде-ния всего имени. Более подходящим был бы поиск частичного соответствия, об-рабатывающий несколько соответствий. Например, выражение с сообщением [myBook lookup: @"steve"]

позволило бы выбрать записи “Steve Kochan", Fred Stevens" и “steven levy". Поскольку может быть обнаружено несколько соответствий, имеет смысл создать массив, содержащий все соответствия, и возвращать этот массив вызывающему методу (см. упражнение 2 в конце главы), например, matches = [myBook lookup: @"steve"]; Удаление записи из адресной книги

Никакой диспетчер адресных книг, позволяющий добавлять записи, не будет полным без возможности удалять записи. Вы можете создать метод removeCard: для удаления конкретной адресной карточки (объекта AddressCard) из адресной книги, или метод remove:, который удаляет конкретного человека по его имени (см. упражнение 6 в конце главы).

Поскольку в файл секции interface внесены некоторые изменения, мы снова показываем его в программе 15.12 с новым методом removeCard:. #import #import "AddressCard.h" @interface AddressBook: NSObject { NSString *bookName; NSMutableArray *book; } -(AddressBook *) initWithName: (NSString *) name; -(void) addCard: (AddressCard *) theCard; -(void) removeCard: (AddressCard *) theCard; -(AddressCard *) lookup: (NSString *) theName; -(int) entries; -(void) list; @end

Ниже приводится новый метод removeCard. -(void) removeCard: (AddressCard *) theCard { [book removeObjectldenticalTo: theCard]; }

Для идентичных объектов мы применяем одно местоположение в памяти. В методе removeObjectldenticalTo: не считаются идентичными две адресные карточки, которые содержат одинаковую информацию, но находятся в разных местах памяти (что может, например, произойти, если создать копию объекта AddressCard).

Кстати, метод removeObjectldenticafTo: удаляет все объекты, идентичные его аргументу. Но это важно только в том случае, если в массиве содержится несколь-ко экземпляров одного и того же объекта.

Можно усложнить подход к равенству объектов, применяя метод removeObject: и написав метод isEqual: для проверки того, что два объекта равны. Если мы используем removeObject:, система автоматически вызывает метод isEqual: для каждого элемента массива, передавая ему два элемента для сравнения. В данном случае адресная книга содержит в качестве своих элементов объекты AddressCard, поэтому в этот класс необходимо добавить метод isEqual: (с замещением метода, который наследуется этим классом из NSObject). В самом методе нужно решить, как определяется равенство. Имеет смысл сравнивать соответствующие имена (name) и адреса электронной почты (email). Если обе пары равны, метод может возвращать значение YES; в противном случае он может возвращать значение N0. Этот метод может иметь следующий вид. -(BOOL) isEqual: (AddressCard *) theCard { if ([name isEqualToString: theCard.name] == YES && [email isEqualToString: theCard .email] == YES) return YES; else return NO; }

Отметим, что другие методы класса NSArray, такие как containsObject: и indexOtObject:, тоже основываются на стратегии isEqual: при проверке на равен-ство двух объектов.

Новый метод removeCard: тестируется в программе 15.12. #import "AddressBook.h" #import int main (int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSString *aName = @" Julia Kochan"; NSString *aEmail = @"[email protected]"; NSString *bName = @"Tony lannino"; NSString *bEmail = @"[email protected]"; NSString *cName = @"Stephen Kochan"; NSString *cEmail = @"[email protected]"; NSString *dName = @"Jamie Baker"; NSString *dEmail = @"[email protected]"; AddressCard *card1 = [[AddressCard alloc] init]; AddressCard *card2 = [[AddressCard alloc] init]; AddressCard *card3 = [[AddressCard alloc] init]; AddressCard *card4 = [[AddressCard alloc] init]; AddressBook *myBook = [AddressBook alloc]; AddressCard *myCard // Сначала создаем четыре адресные карточки [card 1 setName: aName andEmail: aEmail]; [card2 setName: bName andEmail: bEmail]; [card3 setName: cName andEmail: cEmail]; [card4 setName: dName andEmail: dEmail]; myBook = [myBook initWithName: @"Linda’s Address Book"]; // Добавляем несколько карточек в адресную книгу [myBook addCard: cardl]; [myBook addCard: card2]; [myBook addCard: card3]; [myBook addCard: card4]; // Поиск человека по имени NSLog (@"Lookup: Stephen Kochan"); myCard = [myBook lookup: @"Stephen Kochan"]; if (myCard != nil) [myCard print]; else NSLog (@"Not found!");  // Теперь удаление записи из адресной книги [myBook removeCard: myCard]; [туBook list]; // проверка, что ее больше нет [card1 release]; [card2 release]; [card3 release]; [card4 release]; [myBook release]; [pool drain]; return 0; }

Вывод программы 15.12 Lookup: Stephen Kochan (Поиск:) ============================== | | | Stephen Kochan | | [email protected] | | | | | | | | O O | ============================== ======== Contents of: Linda’s Address Book ========= (Содержимое книги) Julia Kochan [email protected] Tony lannino [email protected] Jamie Baker [email protected]

После того, как запись Stephen Kochan в адресной книге найдена, мы передаем результирующий объект AddressCard новому методу removeCard: для удаления. Вывод списка адресной книги подтверждает, что удаление было сделано. Сортировка массивов

Если адресная книга содержит много записей, ее удобно упорядочить в алфа-витном порядке. Добавим метод sort в класс AddressBook и применим метод sortllsingSelector: класса NSMutableArray, В этом методе в качестве аргумента служит селектор, применяемый методом sortllsingSelector: для сравнения двух элементов. Массивы могут содержать объекты любого типа, поэтому единственный способ реализации обобщенного метода сортировки – это проверка порядка элементов массива. Для этого необходимо добавить метод, выполняющий сравнение двух элементов массива. Результат, возвращаемый этим методом, должен иметь тип NSComparisonResult. Метод должен возвращать значение NSOrderedAscending (по возрастанию), если нужно, чтобы метод помещал первый элемент перед вторым элементом в массиве; значение NSOrderedSame, если два элемента равны; значение NSOrderedDescending (по убыванию), если первый элемент должен следовать после второго элемента.

Сначала приводим новый метод сортировки из класса AddressBook. -(void) sort { [book sortUsingSelector: @selector(compareNames:)j; }

Как известно из главы 9, выражение @selector (compareNames:) создает селектор с типом SEL из имени указанного метода; это метод, который используется sortUsingSelector: для сравнения двух элементов массива. Когда требуется выполнить такое сравнение, он вызывает указанный метод, отправляя сообщение первому элементу массива (получателю) для сравнения с аргументом. Возвращаемое значение должно иметь тип NSComparisonResult.

Поскольку элементы нашей адресной книги – это объекты класса AddressCard, метод сравнения должен быть добаален в класс AddressCard. Мы должны вернуться к нашему классу AddressCard и добавить в него метод compareNames:. // Сравнение двух имен из указанных адресных карточек -(NSComparisonResult) compareNames: (id) element { return [name compare: [element name]]; }

Для строкового сравнения двух имен из адресной книги можно использовать метод NSString compare:.

Если добавить метод sort в класс AddressBook и метод compareNames; в класс AddressCard, то мы получим тестовую программу 15.13. #import "AddressBook.h" #import int main (int argc, char *argv(]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSString *aName = @"Julia Kochan"; NSString *aEmail = @"[email protected]"; NSString *bName = @"Tony lannino"; NSString *bErnail = @"[email protected]"; NSString *cName = @"Stephen Kochan"; NSString *cEmail = @[email protected]"; NSString *dName = @"Jamie Baker"; NSString *dEmail = @"[email protected]"; AddressCard *card1 = [[AddressCard alloc] init]; AddressCard *card2 = [[AddressCard alloc] init]; AddressCard *card3 = [[AddressCard alloc] init]; AddressCard *card4 = [[AddressCard alloc] init]; AddressBook *myBook = [AddressBook alloc]; // Сначала задаем четыре адресные карточки [card1 setName: aName andEmail: aEmail]; [card2 setName: bName andEmail: bEmail]; [card3 setName: cName andEmail: cEmail]; [card4 setName: dName andEmail: dEmail]; myBook = [myBook initWithName: @"Linda’s Address Book"]; // Добавляем несколько карточек в адресную книгу [myBook addCard: card1]; [myBook addCard: card2]; [myBook addCard: card3]; [myBook addCard: card4]; // Вывод неотсортированной книги [myBook list]; // Ее сортировка и повторный вывод [myBook sort]; [myBook list]; [card1 release]; [card2 release]; [card3 release]; [card4 release]; [myBook release]; [pool drain]; return 0; }

Вывод программы 15.13 ======== Contents of: Linda’s Address Book == Julia Kochan [email protected] Tony lannino [email protected] Stephen Kochan [email protected] Jamie Baker [email protected] ==================================================== ======== Contents of: Linda’s Address Book == Jamie Baker [email protected] Julia Kochan [email protected] Stephen Kochan [email protected] Tony lannino [email protected]

Отметим, ЧТО сортировка выполняется в порядке возрастания. Вы можете выполнить сортировку в порядке убывания, внеся изменения в метод compareNames: класса AddressCard, обратив смысл возвращаемых значений.

Для работы с объектами-массивами имеется более 50 методов. В таблицах 15.4 и 15.5 приводится список наиболее распространенных методов для работы с немутабельными и мутабельными массивами. NSMutableArray наследует методы класса NSArray, поскольку является его подклассом.

В таблицах 15.4 и 15.5 obj, objl и объявляются произвольными объектами; / – это значение типа NSUInteger, представляющее допустимый номер элемента в массиве, selector – это объект-селектор типа SEL, size имеет тип NSUInteger.

Табл. 15.4. Наиболее распространенные методы класса NSArray Метод Описание +(id) arrayWithObjects: obj1, obj2,... nil Создает новый массив с элементами obj1, obj2, ... -(BOOL) containsObject: obj Определяет, содержится ли objв массиве (используется метод isEqual:). -(NSUInteger) count Указывает число элементов в массиве. -(NSUInteger) indexOfObject: obj Определяет номер первого элемента, содержащего obj(используется метод isEqual:). -(id) objectAtlndex: i Указывает объект, хранящийся в элементе i. -(void) makeObjectsPerformSelector: (SEL) selector Передает каждому элементу массива сообщение, которое указывает selector. -(NSArray *) sortedArrayUsingSelector: (SEL) selector Сортирует массив в соответствии с методом сравнения, который указывает selector. -(BOOL) writeToFile: path automically: (BOOL) flag Записывает массив в указанный с помощью path файл, создавая сначала временный файл, если flag имеет значение YES.

Табл. 15.5. Наиболее распространенные методы класса NSMutableArray Метод Описание +(id) array Создает пустой массив. +(id) arrayWithCapacity: size Создает массив с указанным начальным размером. -(id) initWittiCapacity: size Инициализирует новый выделенный (alloc) массив с указанным начальным размером. -(void) addObject: obj Добавляет obj в конец массива. -(void) insertObject: obj atindex: i Выполняет вставку оbj в элемент i массива. -(void) replaceObjectAtlndex: i withObject: obj Заменяет объект в элементе i массива на obj. -(void) removeObject: obj Удаляет все экземпляры obj из массива. -(void) removeObjectAtlndex: i Удаляет элемент i из массива, смещая влево все элементы, начиная с i. -(void) sortUsingSelector: (SEL)selector Сортирует массив в соответствии с методом сравнения, который указывает selector. 15.4. Объекты-словари

Словарь (dictionary) – это коллекция данных, состоящая из пар ключ-объект. Как в обычном словаре, мы получаем из словаря Objective-C значение (объект) по его кп ючу. Ключи в словаре должны быть уникальными, и они могут быть объектом любого типа, хотя обычно это строки. Значение, соответствующее ключу, тоже может быть объектом любого типа, но не должно быть значение nil.

Словари могут быть мутабельными или немутабельными; в первом случае в них можно динамически добавлять и удалять записи. В словарях можно выполнять поиск по определенному' ключу, их содержимое можно делать перечислимым. В программе 15.14 создается словарь терминов Objective-C, и в нем заполняются первые три записи.

Для использования словарей нужно включить следующую строку. #import #import #import #import #import int main (int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSMutableDictionary *glossary = [NSMutableDictionary dictionary]; // Сохранение трех записей в этом словаре [glossary setOhject: @"A class defined so other classes can inherit from it" forKey: @"abstract class" ]; [glossary setObject: @'To implement all the methods defined in a protocol" forKey: @"adopt"]; [glossary setObject: @''Storing an object for later use" forKey: @"archiving"]; // Их считывание и вывод NSLog (@"abstract class: %@", [glossary objectForKey: @"abstract class"]); NSLog (@"adopt: %@ [glossary objectForKey: @"adopt"]); NSLog (@"archiving: %@", [glossary objectForKey: @"archiving"]); [pool drain]; return 0; }

Вывод программы 15.14 abstract class: A class defined so other classes can inherit from it (абстрактный класс: класс, определенный таким образом, чтобы другие классы могли наследовать из него) adopt: То implement all the methods defined in a protocol (принять: для реализации всех методов, определенных в протоколе) archiving: Storing an object for later use (архивация: сохранение объекта для дальнейшего использования)

С помощью выражения [NSMutableDictionary dictionary]

создается пустой мутабельный словарь. Мы можем добавлять в этот словарь пары ключ-значение с помощью метода setObject:forKey:. После создания словаря мы можем считывать значение для заданного ключа с помощью метода objectForKey:. В программе 15.14 показано считывание и вывод этих трех записей. В более близком к практике приложении пользователь вводит слово, и программа вы-полняет поиск определения этого слова в словаре. Перечисление записей словаря

В программе 15.15 показано, как можно определить словарь с начальными парами «ключ-значение» с помощью метода dictionaryWithObjectsAndKeys:. Мы создадим немутабельный словарь и покажем, как применяется цикл с быстрым пе-речислением для считывания каждого элемента из словаря, по одному ключу за шаг. В отличие от объектов-массивов, объекты-словари не упорядочиваются, поэтому первая пара ключ-объект, помешенная в словарь, не обязательно будет первым ключом, извлекаемым при перечислении. #import < Foundation/NSObject. h> #import #import #import int main (int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSDictionary *glossary = [NSDictionary dictionaryWithObjectsAndKeys: @"A class defined so other classes can inherit from it", @"abstract class", @"To implement all the methods defined in a protocol", @"adopt", @"Storing an object for later use", @"archiving", nil ]; // Вывод всех пар ключ-значение из словаря for ( NSString *key in glossary) NSLog (@"%@%@ key, (glossary objectForKey: key]); [pool drain]; return 0; }

Вывод программы 15.15 abstract class: A class defined so other classes can inherit from it adopt: To implement all the methods defined in a protocol archiving: Storing an object for later use

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

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

Мы только что показали некоторые базовые операции со словарями. В таб-лицах 15.6 и 15.7 приводятся наиболее распространенные методы для работы с немутабельными и мутабельными словарями. Поскольку NSMutableDictionary яв-ляется подмножеством IMSDictionary, он наследует его методы.

В таблицах 15.6 и 15.7 ключи и объекты key, keyl, кеу2, nhj, ohjl и ohj2 – про-извольные объекты, и size – целое без знака (unsigned int) типа NSUInteger.

Табл. 15.6. Наиболее распространенные методы класса NSDictionary Метод Описание -(NSArray *) keysSortedByValueUsingSelector: (SEL) selector Возвращает массив ключей из словаря, отсортированных в соответствии с методом сравнения, который указывает селектор selector. -(NSEnumerator *) objectEnumerator Возвращает объект класса NSEnumerator для всех значений из словаря -(id) objectForKey: key Возвращает объект для указанного ключа key.

Табл. 15.7. Наиболее распространенные методы класса NSMutableDictionary Метод Описание +(id) dictionaryWitb Capacity: size Создает мутабельный словарь с указанным начальным размером size. -(id) initWithCapacity: size Инициализирует новый выделенный (alloc) словарь с указанным начальным размером size. -(void) removeAHObjects Удаляет все записи из словаря. -(void) removeObjectForKey: key Удаляет из словаря запись с указанным ключом key. -(void) setObject: objforKey: key Добавляет в словарь obj для ключа key и заменяет значение, если этот ключ уже существует. 15.5. Объекты-наборы

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

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

В программе 15.16 показаны основные операции с наборами. Предположим, что нам нужно выводить содержимое наборов во время выполнения программы. Создаем новый метод с именем print и добавляем метод print в класс NSSet, создавая новую категорию с именем Printing. NSMutableSet – это подкласс NSSet, поэтому мутабельные наборы тоже могут использовать новый метод print. #import #import #import #import #import // Создание объекта целого типа #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 правильно выводили поля.


    Ваша оценка произведения:

Популярные книги за неделю