Шрифт:
Затем в программе начинается цикл for для поиска простых чисел, начиная с 5, вплоть до kMaxPrime с пропуском промежуточных четных чисел (р += 2).
Для каждого возможного числа р проверяется его делимость на предыдущие простые числа. В случае делимости р не является простым числом. Для ускорения мы проверяем делимость только на простые числа, не превышающие квадратный корень из р. Дело в том, что если число не является простым, оно должно делиться на простое число, которое не больше его квадратного корня. Поэтому выражение р / prevPrime >= prevPrime
верно, earn prevPrime меньше, чем квадратный корень из р.
Если при выходе из цикла do-while флаг isPrime по-прежнему равен YES, зна-чит, мы нашли еще одно простое число. В этом случае р добавляется в массив primes, и выполнение программы продолжается.
Краткое замечание по эффективности. Классы Foundation очень удобны для работы с массивами, однако при работе с большими массивами чисел и сложными алгоритмами нужно научиться выполнять такие задачи с помощью низ-коуровневых конструкций языка для массивов, которые могут оказаться более эффективными сточки зрения использования памяти и скорости выполнения. См. раздел «Массивы» в главе 13. Создание адресной книги
Рассмотрим пример создания адресной книги. Она будет содержать адресные карточки. Для упрощения эти адресные карточки будут содержать только имя человека и его адрес электронной почты. Можно легко расширить эти данные, добавив другую информацию, например, почтовый адрес и номер телефона, но мы оставляем это вам как упражнение в конце главы. Создание адресной карточки
Мы начинаем с определения нового класса AddressCard. Нам нужны средства для создания новой адресной карточки, задания ее полей имени (паше) и электронной почты (email), чтения этих полей и вывода каргочки. В графической среде можно было бы использовать некоторые удобные процедуры, например, из фреймворка Application Kit, чтобы рисовать карточку на экране.
В программе 15.8 показан файл секции interface для нового класса AddressCard. Мы не будем пока синтезировать методы доступа (accessor methods); мы напишем их сами в качестве упражнения. #import <Foundation/NSObject.h> #import <Foundation/NSString.h> @interface AddressCard: NSObject { NSString *name; NSString *email; } -(void) setName: (NSString *) theName; -(void) setEmail: (NSString *) IheEmail; -(NSString *) name; -(NSString *) email; -(void) print; @end
Это легко сделать с помощью файла секции implementation программы 15.8. #import "AddressCard.h" @implementation AddressCard -(void) setName: (NSString *) theName { name = [[NSString alloc] initWithString: theName]; } -(void) setEmail: (NSString *) theEmail { email = [[NSString alloc] initWithString: theEmail]; } -(NSString *) name { return name; } -(NSString *) email { return email; } -(void) print { NS Log (@"===================================="); NSLog (@"| Г); NSLog (@"| %-31s |", Iname UIE8String]); NSLog (@"| %-31s j", [email UTF8String]); NSLog (@"| I"); NSLog (@"| Г); NSLog (@"| Г); NSLog (@"| О О Г); NSLog (@"===================================="); } @end
Можно было бы сделать так, чтобы методы setName: и setEmail: сохраняли объекты непосредственно в своих переменных экземпляра с помощью следующих определений методов. -(void) setName: (NSString *) theName { name = theName; } -(void) setEmail: (NSString *) theEmail { email = theEmail; }
Но тогда объект класса AddressCard не будет владеть своими объектами-чле-нами. Мы уже говорили в главе 8 о получении объектом владения применительно к классу Rectangle, владеющему своим объектом origin.
Определение этих методов следующим способом тоже неверно, поскольку методы AddressCard тоже не будут владеть своими объектами name и email — ими будет владеть NSString. -(void) setName: (NSString *) theName { name = [NSString stringWithString: theName]; } -(void) setEmail: (NSString *) theEmail { email = (NSString stringWithString: theEmail]; }
Вернемся к программе 15.8. Метод print представляет пользователя в виде адресной карточки в формате, напоминающем карточку Rolodex (они исполь-зовались в картотеках). Символы %-31s при вызове NSLog указывают вывод в виде С-строки UTF8 при ширине поля 31 символ с выравниванием полевому краю. Так пользователь сможет брать карточку за правый край.
После создания класса AddressCard мы можем написать тестовую программу для создания адресной карточки, задания ее значений и ее вывода (см. программу 15.8). #import "AddressCard.h" #import <Foundation/NSAutoreleasePool.h> int main (int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSString *aName = @ "Julia Kochan"; NSString *aEmail = @"jewls337(9>axlc.comn; AddressCard *card1 = [[AddressCard alloc] init]; [cardl setName: aName]; [card 1 setEmail: aEmail]; [cardl print]; [cardl release]; [pool drain]; return 0; }
Вывод программы 15.8 ======================================== | | | Julia Kochan | | jewls337@axlc.com | | | | | | | | O O | ========================================
В этой программе строка [cardl release]; применяется для освобождения памяти, которая занята адресной карточкой. Из предыдущих глав вы должны понимать, что высвобождение объекта класса AddressCard таким способом не приводит к освобождению памяти, которую мы выделили для его членов name и email. Чтобы избежать утечки памяти для класса AddressCard, нужно заместить метод dealloc, высвобождая эти члены при освобож-дении памяти для объекта AddressCard. Ниже приводится замещающий метод dealloc для класса AddressCard. -(void) dealloc { [name release]; [email release]; [super dealloc]; }