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

на главную

Жанры

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

Перечислимый (enumerated) тип данных позволяет определять имя для типа данных, которое будет использоваться только для хранения заданного списка значений. В языке Objective-C оператор typedef позволяет вам назначать собственное имя встроенному или производному типу данных. В этой главе мы описываем действия компилятора по преобразованию типов данных при оценке выражений. 10.1. Инициализация классов

Мы уже встречали такой набор действий, когда выделяется память для нового экземпляра объекта, а затем выполняется его инициализация: Fraction *myFract = [[Fraction alloc] init];

После вызова этих методов обычно выполняется присваивание некоторых значений новому объекту: [myFract setTo: 1 over: 3];

Процесс инициализации объекта, после которого ему присваиваются начальные значения, часто объединяют в один метод. Например, можно определить метод initWith::, который инициализирует объект типа fraction (дробь) и присваивает два (неименованных) заданных аргумента его числителю (numerator) и знаменателю (denominator).

Класс, который содержит много методов и переменных экземпляра, обычно имеет несколько методов инициализации. Например, класс NSArray из Foundation framework содержит шесть методов инициализации. initWithArray: initWithArrayxopyltems: initWithContentsOfFile: initWithContentsOfURL: initWithObjects: initWithObjects:count:

Массиву (array) можно выделить память и затем инициализировать его, например, с помощью следующей последовательности: myArray = [[NSArray alloc] initWithArray: myOtherArray];

Принято, что все инициализаторы в классе обычно начинаются с init. Инициализаторы NSArray следуют этому правилу. При написании инициализаторов вы можете придерживаться одной из двух стратегий.

Если ваш класс содержит более одного инициализатора, один из них должен быть вашим назначенным (designated ) инициализатором, и все остальные методы инициализации должны его использовать. Обычно это более сложный метод инициализации (и принимает больше всего параметров). При создании назначенного инициализатора основной код инициализации объединяется в одном методе. При создании подкласса можно затем замещать назначенный инициализатор, чтобы обеспечить правильную инициализацию новых экземпляров. Необходимо следить за тем, чтобы правильно инициализировались любые наследуемые переменные экземпляра. Наиболее простой способ —вызывать сначала назначенный метод инициализации из родительского класса, который обычно называется init, а после этого инициализировать свои собственные переменные экземпляра.

Исходя из этого, метод инициализации initWith:: для класса Fraction может выглядеть следующим образом. -(Fraction *) initWith: (int) n: (int) d { self = [super init]; if (self) [self setTo: n over: d]; return self; }

Этот метод вызывает сначала родительский инициализатор, которым является метод init из NSObject (напомним, что это родительский класс для Fraction).

Вы должны присвоить результат self, поскольку инициализатор имеет право изменять или перемещать объект в памяти.

После инициализации super (и ее успешного завершения, что указывается ненулевым возвращаемым значением) используется метод setTo:over:, чтобы задать числитель (numerator) и знаменатель (denominator) дроби (Fraction). Как и для других методов инициализации, предполагается, что вы возвращаете инициализированный объект.

В программе 10.1 выполняется проверка нового метода инициализации initWith::. Программа 10.1 #import "Fraction.h" int main (int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Fraction *a, *b; a = [[Fraction alloc] initWith: 1: 3]; b = [[Fraction alloc] initWith: 3: 7]; [a print]; [b print]; [a release]; [b release]; [pool drain]; return 0; }

Вывод программы 10.1 1/3 3/7

Когда программа начинает выполнение, она передает метод вызова инициализации всем нашим классам. Если имеется класс и связанный с ним подкласс, родительский класс получает это сообщение первым. Это сообщение передается каждому классу только один раз, и оно гарантированно отправляется до того, как любые другие сообщения будут переданы классу. Ваша цель в этот момент — выполнение инициализации любого класса. Например, вам может потребоваться инициализация некоторых статических переменных, связанных с данным классом. 10.2. Снова об области действия

На область действия переменных в программе можно влиять разными способами: с переменными экземпляра или с обычными переменными, определенными вне или внутри функций. Ниже мы будем использовать термин модуль (module ) при ссылке на любое число определений методов или функций, содержащихся в одном исходном файле. Директивы для управления областью действия переменных экземпляра

Вы уже знаете, что переменные экземпляра имеют область действия, которая ограничивается методами экземпляра, определенными для данного класса. Поэтому любой метод экземпляра может выполнять доступ к свои переменным экземпляра по имени без дополнительных действий. Вы также знаете, что переменные экземпляра наследуются подклассом. Д оступ к переменным экземпляра тоже можно выполнять по имени из любого метода, определенного в этом подклассе. И в этом случае специальные действия тоже не требуются.

Перед переменными экземпляра при объявлении в секции interface можно помещать четыре директивы, чтобы более точно управлять их областью действия.

@protected. Методы, определенные в данном классе и любых подклассах, могут выполнять непосредственный доступ к последующим переменным экземпляра. Это вариант по умолчанию.

@private. Методы, определенные в данном классе (но не в подклассах), могут выполнять непосредственный доступ к последующим переменным экземпляра.

@public. Методы, определенные в данном классе и любых классах или модулях, могут выполнять непосредственный доступ к последующим переменным экземпляра.

@package. Для 64-битных образов доступ к переменной экземпляра может выполняться в любом месте образа, который реализует данный класс.

Если вам нужно определить класс с именем Printer, содержащий две частные переменные экземпляра с именами pageCount и tonerLevel, которые доступны только методам из класса Printer, то вы можете использовать следующую секцию interface. @interface Printer: NSObject { @ private int pageCount; int tonerLevel; @ protected // другие переменные экземпляра } @end

Доступ к этим двум переменным экземпляра нельзя выполнить из любого подкласса класса Printer, поскольку они сделаны частными (private).

Эти специальные директивы действуют как переключатели: все переменные, которые появляются после одной из этих директив (пока не появится правая фигурная скобка, которая являются концом объявлений этих переменных), имеют указанную область действия, если не использована другая директива. В приведенном примере директива @protected гарантирует, что следующие после нее переменные экземпляра будут доступны для методов подклассов и класса Printer.

Поделиться:
Популярные книги

Войны Наследников

Тарс Элиан
9. Десять Принцев Российской Империи
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Войны Наследников

Петля, Кадетский Корпус. Книга пятая

Алексеев Евгений Артемович
5. Петля
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Петля, Кадетский Корпус. Книга пятая

Вперед в прошлое 11

Ратманов Денис
11. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 11

Монстр из прошлого тысячелетия

Еслер Андрей
5. Соприкосновение миров
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Монстр из прошлого тысячелетия

Кай из рода красных драконов

Бэд Кристиан
1. Красная кость
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Кай из рода красных драконов

Тринадцатый V

NikL
5. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый V

Стеллар. Трибут

Прокофьев Роман Юрьевич
2. Стеллар
Фантастика:
боевая фантастика
рпг
8.75
рейтинг книги
Стеллар. Трибут

На границе империй. Том 9. Часть 5

INDIGO
18. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 5

Император Пограничья 7

Астахов Евгений Евгеньевич
7. Император Пограничья
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Император Пограничья 7

Романов. Том 1 и Том 2

Кощеев Владимир
1. Романов
Фантастика:
фэнтези
попаданцы
альтернативная история
5.25
рейтинг книги
Романов. Том 1 и Том 2

Третий Генерал: Тома I-II

Зот Бакалавр
1. Третий Генерал
Фантастика:
городское фэнтези
попаданцы
аниме
сказочная фантастика
5.00
рейтинг книги
Третий Генерал: Тома I-II

Как я строил магическую империю 4

Зубов Константин
4. Как я строил магическую империю
Фантастика:
боевая фантастика
постапокалипсис
аниме
фантастика: прочее
фэнтези
5.00
рейтинг книги
Как я строил магическую империю 4

Миллионщик

Шимохин Дмитрий
3. Подкидыш
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Миллионщик

Виконт. Книга 4. Колонист

Юллем Евгений
Псевдоним `Испанец`
Фантастика:
фэнтези
попаданцы
аниме
7.50
рейтинг книги
Виконт. Книга 4. Колонист