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

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

Жанры

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

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

Рассмотрим программу 9.4. В определении класса Fraction у нас не было

метода с именем noSuchMethod («нет такого метода»). При компиляции этой программы вы получите из-за этого предупреждающие сообщения. #import Traction.h" int main (int arge, char *argv []) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Fraction *f = [[Fraction alloc] init]; [f noSuchMethod]; NSLog (@"Execution continues!'’); [f release]; [pool drain]; return 0; }

Несмотря на эти предупреждающие сообщения, вы можете попытаться продолжить работу и выполнить программу. В этом случае программа будет аварийно завершена с выводом следующих сообщений об ошибках. Вывод программы 9.4 -[Fraction noSuchMethod]: unrecognized selector sent to instance 0x103280 (... нераспознанный селектор передан экземпляру) *** Terminating арр due to uncaught exception ’NSInvalidArgumentException', (Прекращение работы приложения из-за необработанного исключения) reason: ’*** -[Fraction noSuchMethod]: unrecognized selector sent to instance 0x103280’ (причина: ... нераспознанный селектор передан экземпляру) Stack: ( 2482717003, 2498756859, 2482746186, 2482739532, 2482739730 ) Trace/BPT trap

Чтобы избежать аварийного завершения программы, можно поместить оди н или несколько операторов в блоке операторов, имеющем следующий формат. @try { оператор оператор } @catch (NSException *exception) { оператор оператор )

Выполнение программы в блоке @try происходит как обычно. Однако если один из операторов в этом блоке выдает исключение, работа программы нс прекращается, а управление передастся в блок @catch, где продолжается ее выполнение. Внутри этого блока можно обрабатывать исключение. Последовательностью действий в этом случае может быть вывод сообщения об ошибке, очистка и завершение работы программы.

В профамме 9.5 показана обработка исключения. Затем приводится вывод программы. #import "Fraction.h" int main {int arge, char *argv []) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Fraction *f = [[Fraction alloc] init]; @try { [f noSuchMethod]; } @catch (NSException *exception) { NSLog(@"Caught %@%@", [exception name], [exception reason]); } NSLog (@"Execution continues!"); [f release]; [pool drain]; return 0; }

Вывод программы 9.5 *** -[Fraction noSuchMethod]: unrecognized selector sent to instance 0x103280 Caught NSInvalidArgumentException: *** -[Fraction noSuchMethod]: unrecognized selector sent to instance 0x103280 Execution continues! (Выполнение продолжается!)

Если возникает исключительная ситуация, выполняется блок @catch. Объект NSExceptton, который содержит информацию об исключении, передастся в этот блок как аргумент. Мметод name считывает имя исключения, а метод reason указывает причину (которую система runtime раньше выводила автоматически). После выполнения последнего оператора в блоке @catch (здесь только один оператор) программа продолжает выполнение, начиная с оператора, который непосредственно следует за этим блоком. В данном случае мы выполняем вызов NSLog, чтобы подтвердить, что выполнение не было прекращено.

Это очень простой пример, показывающий, как перехватывать исключения в профамме. Можно также использовать блок @finally, чтобы включить код, выполняемый независимо от возникновения исключительной ситуации в каком- либо операторе блока @try.

Директива @throw позволяет создавать ваше собственное исключение. Ее можно использовать для создания конкретного исключения или

внугри блока @catch для создания той же исключительной ситуации, которая вызвала переход в этот блок: @throw;

Это может потребоваться после вашей собственной обработки исключения (например, после выполнения операций очистки). После этого вы можете передать системе остальную часть работы. И, наконец, у вас может быть несколько блоков @catch, которые следуют в определенном порядке для перехвата и обработки исключений различного типа. Упражнения

Что произойдет, если вставить выражение с сообщением [compResult reduce]; в профамму 9.1 после того, как выполнено сложение (но до выполнения release для compResult)? Попробуйте и посмотрите, что получится.

Можно ли переменной dataValue типа id (определенной в профамме 9.2) присвоить объект класса Rectangle в соответствии с его определением в главе 8? Иначе говоря, является ли допустимым оператор dataValue = [[Rectangle alloc] init]; Почему?

Добавьте метод print к классу XYPoint, определенному в главе 8. Он должен выводить точку в формате (х,у). Затем внесите изменения в программу 9.2, чтобы включить объект типа XYPoint. Эта модифицированная программа должна создавать объект типа XYPoint, задавать его значение, присваивать его переменной dataValue типа id и затем выводить его значение.

Вспомните, что говорилось в этой главе о типах ар1ументов и возвращаемых значений, и модифицируйте методы add: в классах Fraction и Complex, чтобы принимать и возвращать объекты типа id. Затем напишите программу, которая включает следующую последовательность кода. result = [dataValuel add: dataValue2]; [result print];

Здесь result, dataValuel и dataValue2 — это объекты типа id. He забудьте задать образом значения dataValuel и dataValue2 в программе и освободить (release) все объекты, прежде чем завершить программу.

Примечание. Вам придется изменить имна этих методов. Системный класс NSObjectController тоже содержит метод add:. Как говорилось выше в разделе «Типы аргументов и возвращаемых значений при динамическом контроле типов», в случае существования нескольких методов с одним именем в разных классах, если на этапе компиляции тип получателя неизвестен, компилятор выполняет проверку согласованности типов аргументов и возвращаемого значения с методами, имеющими одинаковые имена.

Используя определения классов Fraction и Complex, заданные в этой книге, и определения Fraction *fraction = [[Fraction alloc] init]; Complex *complex = [[Complex alloc] init]; id number = [[Complex alloc] init]; определите возвращаемое значение для следующих выражений с сообщениями. Затем введите их в программу, чтобы проверить результаты. [fraction isMemberOfClass: [Complex class]]; [complex isMemberOfClass: [NSObject class]]; [complex isKindOfClass: [NSObject class]]; [fraction isKindOfClass: [Fraction class]]; [fraction respondsToSelector: @selector (print)]; [complex respondsToSelector: @selector (print)]; [Fraction instancesRespondToSelector: @selector (print)]; [number respondsToSelector: @selector (print)]; [number isKindOfClass: [Complex class]]; [number respondsToSelector: @selector (release)]; [[number class] respondsToSelector: @selector (alloc)];

Глава 10. Более подробно о переменных и типах данных

В этой главе мы поговорим об области действия переменных, методах инициализации для объектов и типах данных. В главе 7 мы кратко обсуждали область действия переменных экземпляра, статические и локальные переменные. Теперь мы более подробно поговорим о статических переменных и введем понятие глобальных и внешних переменных. Для компилятора Objective-C можно задавать директивы, позволяющие контролировать область действия переменных экземпляра. В этой главе мы рассмотрим их.

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

Печать Пожирателя

Соломенный Илья
1. Пожиратель
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Печать Пожирателя

Имя нам Легион. Том 8

Дорничев Дмитрий
8. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 8

Агенты ВКС

Вайс Александр
3. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Агенты ВКС

Сильнейший Столп Империи. Книга 4

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

Поступь Империи

Ланцов Михаил Алексеевич
7. Сын Петра
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Поступь Империи

Японская война 1904. Книга третья

Емельянов Антон Дмитриевич
3. Второй Сибирский
Фантастика:
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Японская война 1904. Книга третья

Неудержимый. Книга XVII

Боярский Андрей
17. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XVII

Треск штанов

Ланцов Михаил Алексеевич
6. Сын Петра
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Треск штанов

Спасите меня, Кацураги-сан! Том 4

Аржанов Алексей
4. Токийский лекарь
Фантастика:
городское фэнтези
попаданцы
дорама
фэнтези
5.00
рейтинг книги
Спасите меня, Кацураги-сан! Том 4

Стражи душ

Кас Маркус
4. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Стражи душ

Вдова на выданье

Шах Ольга
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Вдова на выданье

Князь Андер Арес 2

Грехов Тимофей
2. Андер Арес
Фантастика:
рпг
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Князь Андер Арес 2

Неучтенный элемент. Том 1

NikL
1. Антимаг. Вне системы
Фантастика:
городское фэнтези
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 1

Идеальный мир для Лекаря 17

Сапфир Олег
17. Лекарь
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 17