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

на главную - закладки

Жанры

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

Поскольку тип объекта, хранящегося в переменной id, во время компиляции может быть неизвестен, некоторые проверки откладываются до выполнения программы (runtime). Рассмотрим следующую последовательность кодов. Fraction *f1 = [[Fraction alloc] init]; [f1 setReal: 10.0 andlmaginary: 2.5];

Поскольку метод setReakandlmaginary: применяется к комплексным числам, а не к дробям, при компиляции программы, содержащей эти строки, появится предупреждающее сообщение. ргодЗ.т: In function 'main':(B функции 'main') prog3.m:13: warning: ’Fraction' does not respond to 'setReakandlmaginary:' (предупреждение: объект типа 'Fraction'

не отвечает на 'setReakandlmaginary:')

Компилятору Objective-C известно, что И является объектом класса Fraction, поскольку он был объявлен именно так. При появлении выражения с сообщением [Н setReal: 10.0 andlmaginary: 2.5];

ему стало известно, что класс Fraction не содержит метода setReal:andlmaginary: (и не наследует его). Поэтому компилятор выдает предупреждающее сообщение.

Теперь рассмотрим следующую последовательность кодов. id dataValue = [[Fraction alloc] init]; [dataValue setReal: 10.0 andlmaginary: 2.5];

Компилятор не выводит предупреждающего сообщения, поскольку во время обработки исходного файла ему неизвестно, какой тип объекта сохраняется в dataValue.

Сообщение об ошибке не появится, пока вы не запустите программу, содержащую эти строки. Сообщение об ошибке может выглядеть следующим образом. objc: Fraction: does not recognize selector -setReakandlmaginary: (не распознается селектор -setReakandlmaginary) dynamic3: received signal: Abort trap (получен сигнал: аварийное прерывание) When attempting to execute the expression (При попытке выполнить выражение) [dataValue setReal: 10.0 and I maginary: 2.5];

Система runtime сначала проверяет тип объекта, хранящегося внутри dataValue. Поскольку dataValue содержит дробь (объект Fraction), система runtime проверяет, определен ли метод setReal:andlmaginary: для класса Fraction. Поскольку это не так, выдается сообщение, и выполнение программы прекращается. 9.4. Тип данных id и статический контроль типов

Если тип данных id можно использовать для хранения любого объекта, так почему бы нам не объявлять все объекты с типом id? Этого не следует делать по нескольким причинам.

Во-первых, определяя переменную как объект из определенного класса, мы используем так называемый статический контроль типов (static typing). Слово статический означает, что переменная всегда используется для хранения объектов из определенного класса, поэтому класс объекта, хранящегося в этом типе, заранее определен, то есть является статическим. При использовании статического контроля типов компилятор обеспечивает согласованное использование этой переменной во всей программе. Компилятор может проверить, определен ли (или унаследован) метод, применяемый к объекту, и если нет, то выводит предупреждающее сообщение. Таким образом, если вы объявляете в своей программе переменную класса Rectangle с именем myRect, то компилятор проверяет, все ли методы, которые вы вызываете для myRect, определены в классе Rectangle или наследуются из его суперкласса.

Примечание. Определенные приемы позволяют вызывать методы, который указываются самой переменной, в таком случае компилятор не может выполнить проверку.

Но если проверка будет выполнена во время выполнения, почему вас должен интересовать статический контроль типов? Дело в том, что лучше выявить ошибки на

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

Еще одним доводом к применению статического контроля типов является то, что он делает ваши программы более удобными для чтения. Рассмотрим объявление id f1;

и сравним его с Fraction *f1;

Конечно, второе объявление лучше, поскольку в нем указывается предполагаемое использование переменной И. Сочетание статического контроля типов и осмысленных имен переменных позволяет делать программы самодоку- ментируемыми. Типы аргументов и возвращаемых значений при динамическом контроле типов

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

Компилятор выполняет проверку на согласованность в объявлениях каждого класса, которые он встречает. Если один или несколько методов не согласуются с типом аргумента или возвращаемого значения, компилятор выводит предупреждающее сообщение. Например, оба класса, Fraction и Complex, содержат метод add:, но класс Fraction принимает в качестве аргумента и возвращает объект типа Fraction, а класс Complex - объект типа Complex. Если trad и myFract - объекты типа Fraction, a compl и myComplex — объекты типа Complex, то определения result = [myFract add: trad];

и result = [myComplex add: compl];

не вызовут проблемы. В обоих случаях получатель сообщения доступен для статического контроля типов и компилятор может проверить согласованность при использовании метода, поскольку он определен в классе получателя. Если dataValuel и dataValue2 — переменные типа id, то выражение result = [dataValuel add: dataValue2];

заставляет компилятор генерировать код для передачи данного аргумента методу add: и обработки его возвращаемого значения, делая некоторые предположения.

Во время выполнения система runtime Objective-C проверит конкретный класс объекта, хранящегося в dataValuel, и выберет метод из подходящего класса для выполнения. Однако в более общем случае компилятор может генерировать неверный код для передачи методу аргументов или обработки его возвращаемого значения. Это может произойти, например, если один метод принял в качестве аргумента какой-либо объект, а другой — значение с плавающей точкой, или один метод возвратил объект, а другой — целое значение. Если методы отличаются только типом объекта (например, метод add: класса Fraction принимает в качестве аргумента и возвращает объект типа Fraction, а метод add: класса Complex принимает в качестве аргумента и возвращает объект типа Complex), то компилятор же будет генерировать правильный код, поскольку адреса памяти (то есть указатели) в обоих случаях будут передаваться как ссылки на объекты. 9.5. Как задавать вопросы о классах

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

Третье правило диверсанта

Бычков Михаил Владимирович
Фантастика:
постапокалипсис
5.67
рейтинг книги
Третье правило диверсанта

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

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

Моров. Том 1 и Том 2

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

Законы Рода. Том 4

Мельник Андрей
4. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 4

Ларь

Билик Дмитрий Александрович
10. Бедовый
Фантастика:
городское фэнтези
мистика
5.75
рейтинг книги
Ларь

Варвара Асенкова

Алянский Юрий Лазаревич
Корифеи русской и зарубежной сцены
Документальная литература:
биографии и мемуары
5.00
рейтинг книги
Варвара Асенкова

Буря империи

Сай Ярослав
6. Медорфенов
Фантастика:
аниме
фэнтези
фантастика: прочее
эпическая фантастика
5.00
рейтинг книги
Буря империи

Шатун. Лесной гамбит

Трофимов Ерофей
2. Шатун
Фантастика:
боевая фантастика
7.43
рейтинг книги
Шатун. Лесной гамбит

Газлайтер. Том 19

Володин Григорий Григорьевич
19. История Телепата
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Газлайтер. Том 19

На границе империй. Том 6

INDIGO
6. Фортуна дама переменчивая
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.31
рейтинг книги
На границе империй. Том 6

Девятый

Каменистый Артем
1. Девятый
Фантастика:
боевая фантастика
попаданцы
9.15
рейтинг книги
Девятый

Локки 5. Потомок бога

Решетов Евгений Валерьевич
5. Локки
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Локки 5. Потомок бога

Эмиссар

Листратов Валерий
8. Ушедший Род
Фантастика:
боевая фантастика
аниме
попаданцы
7.50
рейтинг книги
Эмиссар

Эволюционер из трущоб. Том 6

Панарин Антон
6. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Эволюционер из трущоб. Том 6