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

ЖАНРЫ

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

Поместим объявление этого метода в файл секции interface, а его определение — в файл секции implementation и напишем тестовую программу для опробования этого метода. Это программа 15.11 и ее вывод. #import "AddressBook.h" #import <Foundation/NSAutoreleasePool.h> int main (int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSString *aName = @ "Julia Kochan"; NSString *aEmail = @"jewls337@axlc.com"; NSString *bName = @"Tony lannino"; NSString *bEmail = @"tony.iannino@techfitness.com"; NSString *cName = @"Stephen Kochan"; NSString *cEmail = @"steve@kochan-wood.com"; NSString *dName = Jamie Baker"; NSString *dEmail = @"jbaker@kochan-wood.com"; 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 | | steve@kochan-wood.com | | | | | | | | 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 <Foundation/NSArray.h> #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 <Foundation/NSAutoreleasePool.h> int main (int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSString *aName = @" Julia Kochan"; NSString *aEmail = @"jewls337@axlc.com"; NSString *bName = @"Tony lannino"; NSString *bEmail = @"tony.iannino@techfitness.com"; NSString *cName = @"Stephen Kochan"; NSString *cEmail = @"steve@kochan-wood.com"; NSString *dName = @"Jamie Baker"; NSString *dEmail = @"jbaker@kochan-wood.com"; 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 | | steve@kochan-wood.com | | | | | | | | O O | ============================== ======== Contents of: Linda’s Address Book ========= (Содержимое книги) Julia Kochan jewls337@axlc.com Tony lannino tony.iannino@techfitness.com Jamie Baker jbaker@kochan-wood.com

После того, как запись 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 <Foundation/NSAutoreleasePool.h> int main (int argc, char *argv(]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSString *aName = @"Julia Kochan"; NSString *aEmail = @"jewls337@axlc.com"; NSString *bName = @"Tony lannino"; NSString *bErnail = @"tony.iannino@techfitness.com"; NSString *cName = @"Stephen Kochan"; NSString *cEmail = @nsteve@kochan-wood.com"; NSString *dName = @"Jamie Baker"; NSString *dEmail = @"jbaker@kochan-wood.com"; 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; }

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