Программирование на Objective-C 2.0
Шрифт:
Вес числовые типы данных, с которыми мы работали до сих пор (такие, как int, float и long) это базовые типы данных в Objective-C. Они не являются объектами, мы не можем передавать им сообщения. Однако время от времени нам нужно работать с ними как с объектами. Например, объект- класса Foundation NSArray позволяет задавать массив, в котором можно сохранять значения. Эти значения должны быть объектами. В таких массивах нельзя непосредственно сохранять базовые типы данных. Вместо этого для сохранения любого из базовых числовых типов данных (включая тип данных char) служит класс NSNumber. Он позволяет создавать объекты из этих типов данных (см. программу 15.1). // Работа с числами #import <Foundation/NSObject.h> #import <Foundation/NSAutoreleasePool.h> #import <Foundation/NSValue.h> #import <Foundation/NSString.h> int main (int arge, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] initj; NSNumber *myNumber, *floalNumber, *inlNumber; NSInteger mylnt; //
Вывод программы 15.1 100 abcdef X 100 1.2345e+19 0 Numbers are equal (Числа равны) First number is less than second (1 -e число меньше 2-го)
Файл <Foundation/NSValue.h> требуется для работы с числами из класса NSNumber. Краткий обзор автоматически высвобождаемого пула (autorelease pool)
Первая строка программы 15.1 присутствовала в каждой программе этой книги. В следующей строке выполняется резервирование пространства в памяти для автоматически высвобождаемого пула (пула автоматического освобождения памяти, autorelease-пул), который назначается для переменной pool. NSAutoreleasePool * pool = [ [ NSAutoreleasePoolalloc] init];
Autorelease-пул автоматически освобождает память, занимаемую объектами, когда объект добавляется в этот пул. Объект добавляется в пул, когда ему передается сообщение autorelease. Когда пул высвобождается, то высвобождаются и все объекты, которые были в него добавлены. Все такие объекты ликвидируются, если для них не было указано, что они существуют вне области действия autorelease-пула (это указывается счетчиками ссылок — reference count).
Обычно вам не нужно думать о высвобождении объекта, возвращаемого ка-ким-либо методом Foundation. Иногда этим объектом владеет метод, который возвращает его. Иногда объект создается заново и добавляется в autoreiease-пул самим методом. Однако, как описывается в части I, вы все же должны высво-бождать любые объекты (включая объекты Foundation), которые создаете явным образом с помощью метода alloc, когда прекращаете их использование.
Примечание. Вы также должны высвобождать объекты, создаваемые методом сору (см. главу 17).
В главе 17 дается полное описание счетчиков ссылок, autorelease-пула и кон-цепции автоматической сборки мусора (garbage collection).
Вернемся к программе 15.1. Класс NSNumber содержит много методов, по-зволяющих создавать объекты NSNumber с начальными значениями. Например, в строке intNumber = [NSNumber numberWithlnteger: 100];
создается объект из целой переменной, значение которой равно 100.
Значение, которое считывается из объекта класса NSNumber, должно быть согласовано с типом значения объекта. Так, в следующем операторе программы выражение [intNumber integerValue]
используется для считывания целого значения, хранящегося в intNumber, и оно сохраняется в переменной mylntTHnaNSInteger. Отметим, что NSInteger - не объект, а typedef-определение для базового типа данных. Это тип long для 64-битных систем или тип int для 32-битных систем. Аналогичный оператор typecef задан для NSUInteger, чтобы работать с целыми без знака (unsigned).
При вызове NSLog выполняется приведение типа NSInteger mylnt к long. Симво-лы формата %li обеспечивают корректную передачу и вывод значен ия, даже если программа компилируется для 32-битной архитектуры.
Для каждого базового значения метод class выделяет память для объекта NSNumber и присваивает
ему указанное значение. Имена этих методов начи-наются с numberWith, после чего следует тип, например, numberWithLong:, numberWithFloat: и т.д. Кроме того, можно использовать методы экземпляра, что-бы присвоить объекту NSNumber (для которого была выделена память) указанное значение. Имена этих методов начинаются с initWith, например, initWithLong: и initWithFloat:.В таблице 15.1 приводится список методов класса и экземпляра, с помощью которых можно задавать значения для объектов @@ NSNumber, и соответству-ющие методы экземпляра для считывания их значений.
Табл. 15.1. Методы создания и считывания значений объектов NSNumber Метод,класса для создания и инициализации Метод экземпляра для инициализации Метод экземпляра для считывания numberWithChar: InitWithChar: charValue numberWthUnsignedChar: initWthUnsignedChar: unsignedCharValue numberWithShort: initWithShort: shortValue numberWithUnsignedShort: initWithllnsignedShort: unsignedShortValue numberWithlnteger: initWithlnteger: integerValue numberWithUnsignedlnteger: initWithllnsignedlnteger: unsignedlntegerValue numberWithlnt: initWithlnt: intValueunsigned numberWithllnsignedlnt: initWithUnsignedlnt: unsignedlntValue numbefWithLong: initWithLong: longValue numbetWithUnsignedLong: inifWithUnsignedLong: unsignedLongValue numberWithLonglong: initWithLongLong: longlongValue numberWithllnsignedLongLong: initWithUnsignedLongLong: unsigned LongLongValue numberWithFloat: initWithFloat: floatValue numberWithDouble: initWthDouble: doubleValue numberWthBool: initWithBool: boolValue
Вернемся к программе 15.I. Методы класса служат для создания объектов NSNumber типа long, char, float и double. Рассмотрим, что происходит после созда-ния объекта типа double с помощью строки myNumber = [NSNumber numberWithDouble: 12345е+15];
и последующей (неверной) попытки считывания и вывода его значения с помощью строки NSLog (@"%i", [myNumber integerValue]};
Выводится результат О
Кроме того, мы не получаем от системы сообщения об ошибке. В общем случае именно вы должны обеспечить правильность считывания значения после его сохранения в объекте NSNumber.
В операторе if в выражении с сообщением [intNumber isEqualToNumber: floatNumber]
метод isEqualToNumber: выполняет числовое сравнение двух объектов NSNumber по возвращаемому булевому значению.
Метод compare: позволяет сравнивать числовые значения. Выражение с со-общением [intNumber compare: myNumber]
возвращает значение NSOrderedAscending, если числовое значение, хранящееся в intNumber, меньше числового значения, содержащегося в myNumber; возвращает значение NSOrderedSame, если эти два числа равны; возвращает значение NSOrderedDescending, если первое число больше второго. Эти возвращаемые значении определены в заголовочном файле NSObjecth.
Отметим, что вы не можете реинициализировать значение созданного ранее объекта NSNumber. Например, с помощью приведенного ниже оператора нельзя задать значение целого элемента, сохраненного в объекте NSNumber myNumber. [myNumber initWithlnt: 1000];
При выполнении программы этот оператор даст ошибку. Все числовые объекты должны создаваться заново, а это означает, что нужно вызывать либо один из методов первого столбца таблицы 15.1 класса NSNumber, либо один из методов столбца 2 с результатом метода alloc. myNumber = [[NSNumber alloc] initWithlnt: 1000];
Конечно, при таком способе создания объекта myNumber вы сами должны высвобождать занимаемую им память с помощью оператора [myNumber release];
Мы будем использовать объекты класса NSNumber в остальных программах этой главы. 15.2. Строковые объекты
Мы уже работали со строковыми объектами в предыдущих главах. Заключая последовательность символов в кавычки, как в @"Programming is fun" (Программировать интересно),
мы создаем в Objective-C объект символьной строки. Для работы с объектами символьных строк Foundation framework поддерживает класс с именем NSString. С-строки состоят из символов типа char, а объекты класса NSString состоят из символов типа unichar. Unichar-символ - это многобайтный символ, соответству-ющий стандарту Unicode. Это позволяет работать с наборами символов, содер-жащими буквально миллионы символов. Вам не нужно заботиться о внутреннем представлении этих символов в строках, поскольку класс NSString автоматически делает это для вас. С помощью методов из этого класса легко разрабатывать приложения, доступные для локализации, то есть для работы на различных языках по всему миру.