Вход/Регистрация
Программирование на Objective-C 2.0
вернуться

Кочан Стивен

Шрифт:

Имеются и другие методы. Один из них позволяет спрашивать, согласуется ли объект с определенным протоколом (см. главу 11). Другие позволяют спрашивать о динамически разрешаемых методах (в этой книге они не рассматриваются).

Чтобы создать объект-класс из имени класса или другого объекта, нужно передать ему сообщение class. Например, чтобы получить объект-класс из класса с именем Square, напишите строку [Square class]

Если mySquare является экземпляром объекта типа Square, то для получения его объекта-класса нужно написать [mySquare class]

Чтобы проверить, являются ли объекты, хранящиеся в переменных obj1 и obj2, экземплярами одного класса, нужно написать строку if ([obj1 class] == [obj2 class])

Чтобы убедиться, что объект myFract является членом класса Fraction, нужно проверить результат выражения [myFract isMemberOfClass: [Fraction class]]

Чтобы генерировать один из так называемых селекторов, которые приводятся в таблице 9.1, нужно применить директиву @selector к имени метода. В следующей строке создается значение типа SEL для метода с именем alloc, который является наследуемым методом из класса NSObject. (@selector (alloc)

В следующем выражении создается селектор для метода setTo:over:, который мы реализовали в классе Fraction (вспомните о двоеточияхв именах методов). (@selector (setTo:over:)

Чтобы убедиться, что экземпляр класса Fraction отвечает на метод setTo:over:, можно проверить возвращаемое значение из следующего выражения. [Fraction instancesRespondToSelector: (@selector (setTo:over:)]

Эта проверка охватывает и наследуемые, и непосредственно определенные в определении класса методы.

Метод performSelector: и его вариации (не показанные в таблице 9.1) позволяют передавать объекту сообщение, где сообщение может быть селектором, хранящимся внутри переменной. Рассмотрим следующую последовательность кода. SEL action; id graphicObject; action = @selector (draw); [graphicObject performSelector: action];

Метод, указанный переменной action типа SEL, передается графическому объекту, который хранится в graphicObject. Предполагается, что действие (action) может изменяться во время выполнения программы в зависимости от ввода пользователя, несмотря на указанное действие draw. Чтобы убедиться, что объект может ответить на данное действие, нужно использовать, например, следующую последовательность. if ([graphicObject respondsToSelector: action] == YES) [graphicObject perform: action] else // здесь должен быть код для обработки ошибок

Примечание. Вы можете отлавливать ошибку, переопределив метод doesNotRecognize:. Этот метод вызывается, когда классу передано нераспознаваемое сообщение и в качестве аргумента передан нераспознаваемый селектор. Можно применять и другие стратегии. Например, с помощью метода forward:: можно перенаправлять сообщение для обработки. Всегда можно передавать метод и перехватывать возникшую исключительную ситуацию. Мы рассмотрим этот способ чуть позже.

В программе 9.3 задаются некоторые вопросы о классах Square и Rectangle, определенных в главе 8. Постарайтесь предсказать результаты этой программы. #import "Square.h" int main (int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Square *mySquare = [[Square alloc] init]; // Проверка с помощью isMemberOf: if ( [mySquare isMemberOfClass: [Square class]] == YES ) NSLog (@"mySquare is a member of Square class"); if ( [mySquare isMemberOfClass: [Rectangle class]] == YES ) NSLog (@"mySquare is a member of Rectangle class"); if ( [mySquare isMemberOfClass: [NSObject class]] == YES ) NSLog (@"mySquare is a member of NSObject class"); II Проверка с помощью isKindOf: if ( [mySquare isKindOfClass: [Square class]] == YES ) NSLog (@"mySquare is a kind of Square"); if ( [mySquare isKindOfClass: [Rectangle class]] == YES ) NSLog (@"mySquare is a kind of Rectangle"); if ( [mySquare isKindOfClass: [NSObject class]] == YES ) NSLog (@"mySquare is a kind of NSObject"); // Проверка с помощью respondsTo: if ( [mySquare respondsToSelector: @selector (setSide:)] == YES ) NSLog (@"mySquare responds to setSide: method"); if ( [mySquare respondsToSelector: @selector (setWidth:andHeight:)] == YES ) NSLog (@"mySquare responds to setWidth:andHeight: method"); if ( [Square respondsToSelector: @selector (alloc)] == YES ) NSLog (@"Square class responds to alloc method"); // Проверка с помощью instancesRespondTo: if ([Rectangle instancesRespondToSelector: @selector (setSide:)] == YES) NSLog (@"lnstances of Rectangle respond to setSide: method"); if ([Square instancesRespondToSelector: @selector (setSide:)] == YES) NSLog (@"lnstances of Square respond to setSide: method"); if ([Square isSubclassOfClass: [Rectangle class]] == YES) NSLog (@"Square is a subclass of a rectangle"); [mySquare release]; [pool drain]; return 0; }

Эта программа должна быть создана с файлами секции implementation для классов Square, Rectangle и XYPoint, которые были рассмотрены в главе 8.

Вывод программы 9.3 mySquare is a member of Square class (mySquare является членом класса Square) mySquare is a kind of Square (mySquare происходит из Square) mySquare is a kind of Rectangle mySquare is a kind of NSObject mySquare responds to setSide: method (mySquare отвечает на метод setSide:) mySquare responds to setWidthiandHeight: method Square class responds to alloc method (Square отвечает на метод alios) Instances of Square respond to setSide: method (Экземпляры mySquare отвечают на метод setSide:) Square is a subclass of a rectangle (Square - это подкласс класса Rectangle)

Вывод программы 9.3 вполне понятен. isMemberOfClass: прозеряет непосредственное членство в классе, a isKindOfClass: проверяет членство в иерархии наследования. mySquare является членом класса Square и «происходит» из Square, Rectangle и NSObject, поскольку входи т в иерархию этою класса (очевидно, что все объекты должны возвращать значение YES для проверки isKindOf: по классу NSObject, если только вы не определили новый корневой объект).

В проверке if ( [Square respondsTo: @selector (alloc)] == YES )

определяется, отвечает ли класс Square на метод класса alloc. Это так, поскольку он унаследован из корневого объекта NSObject. Вы всегда можете использовать непосредственно имя класса в качестве получателя в выражении для сообщения и не обязаны включать [Square class]

в предыдущее выражение (хотя могли бы это сделать).

Но это единственное место, где можно без этого обойтись. В других местах для получения объекта-класса нужно обязательно применять метод class. 9.6. Обработка исключительных ситуаций с помощью @try

  • Читать дальше
  • 1
  • ...
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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