Программирование на Objective-C 2.0
Шрифт:
Объекты класса NSString широко используются в этой книге. Для разбора арок на маркеры нужно рассмотреть класс Foundation NSScanner. 15.3. Объекты-массивы
Массив в Foundation — это упорядоченный набор объектов. Чаще всего (но не обязательно) элементы массива имеют один определенный тип. Аналогично мутабельным и немутабсльным строкам, существуют мутабельные и немута- бельные массивы. Для работы с немутабельными (immutable) массивами исполь-зуется класс NSArray; для мутабельных (mutable) массивов используется класс NSMutableArray. Последний класс является подклассом предыдущего и наследует его методы. Для работы с объектам и-массивам и в программах нужно включить строку #import <Foundalion/NSArray.h>
В
Вывод программы 15.6 Month Name 1 January 2 February 3 March 4 April 5 May 6 June 7 July 8 August 9 September 10 October 11 November 12 December
Метод этого класса arrayWithObjects: создает массив со списком объектов в виде его элементов. Объекты перечисляются по порядку и разделяются запятыми. Это специальный синтаксис методов, которые принимают переменное число аргументов. Чтобы закончить список, нужно поставить nil в качестве последнего значения списка (nil не сохраняется внутри массива).
В программе 15.7 массиву monthNames присваиваются 12 строковых значений в виде аргументов для метода arrayWithObjects:.
Элементы массива идентифицируются своим индексом (порядковым номе-ром). Аналогично объектам класса NSString, индексирование начинается с нуля, поэтому массив, содержащий 12 элементов, имеет допустимые индексы 0-11. Метод objectAdndex: считывает элемент массива но его индексу.
В этой программе каждый элемент из массива считывается с помощью метода objectAUndex: в цикле for. Каждый считываемый элемент выводится с помощью NSLog.
В программе 15.7 создается таблица простых (prime) чисел. Поскольку про-стые числа добавляются в массив по мере их создания, здесь требуется мута- бельный массив. Память для объекта primes класса NSMutableArray выделяется с помощью метода arrayWithCapacity:. Указанный аргумент 20 задаст начальный размер массива; размер мутабельного массива автоматически увеличивается во время выполнения программы.
Хотя простые числа являются целыми, мы не можем сохранять значения типа int внутри этого массива. Данный массив может содержать только объекты, поэтому нам нужно сохранять в массиве primes целые объекты класса NSNumber. #import <Foundalion/NSObject.h> #import <Foundation/NSArray.h> #import <Foundation/NSString.h> #import <Foundation/NSAutoreleasePool.h> #import <Foundation/NSValue.h> #define MAXPRIME 50 int main (int argc, char *argv[]) { int i, p, prevPrime; BOOL isPrime; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // Создание массива для хранения простых чисел NSMutableArray *primes = [NSMutableArray arrayWithCapacity: 20]; // Сохранение в массиве первых двух простых чисел (2 и 3) [primes addObject: [NSNumber numberWithlnteger: 2]]; [primes addObject: [NSNumber numberWithlnteger: 3]]; // Вычисление остальных простых чисел for (р = 5; р <= MAXPRIME; р += 2) { // проверяется, что р - простое число isPrime = YES; i = 1; do { prevPrime = [[primes objectAtlndex: i] integerValue]; if (p % prevPrime == 0) isPrime = NO; ++i; } while (isPrime == YES && p / prevPrime >= prevPrime); if (isPrime) [primes addObject: [NSNumber numberWithlnteger: p]]; } //
Вывод программы 15.7 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47
kMaxPrime определяется как максимальное простое число для вычислений (в данном случае 50).
После выделения памяти для массива primes задаются два первых элемента массива с помощью следующих операторов. [primes addObject: [NSNumber numberWithlnteger: 2]]; [primes addObject: [NSNumber numberWithlnteger: 3]];
Метод addObject: добавляет объект в коней массива. В данном случае добав-ляются объекты класса NSNumber, создаваемые соответственно из целых значе-ний 2 и 3.
Затем в программе начинается цикл 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