Рубріки: Теория

Objective-C: обсуждаем проблемы dynamic binding

Ігор Грегорченко

Динамическое связывание — это определение метода для его вызова во время выполнения программы, а не во время компиляции. Динамическое связывание также еще называют поздним связыванием. В Objective-C все методы определяются динамически во время выполнения. Точный выполняемый код определяется как именем метода (селектором), так и принимающим объектом. Более подробно о специфике и проблемах dynamic binding — в этой обзорной статье под катом.


Objective-C является по своей сути динамической программной средой. Как можно больше решений откладывается до времени выполнения, а не принимается во время компиляции. Например:

  • Объекты динамически выделяются (через методы класса, такие как alloc).
  • Объекты динамически типизируются. На любой объект может ссылаться переменная типа id. Точный класс объекта и, соответственно, конкретные методы, которые он предоставляет, определяются только во время выполнения, но эта задержка не мешает написанию кода, который посылает сообщения этим объектам.
  • Сообщения динамически привязываются к методам. Процедура runtime сопоставляет селектор метода в сообщении с конкретной реализацией метода, которая «принадлежит» объекту-приемнику. Это сопоставление может динамически изменяться или модифицироваться, чтобы изменить поведение приложения и ввести такие аспекты как протоколирование (без перекомпиляции).

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

Пример динамического связывания

Итак, динамическое связывание (dynamic binding) позволяет реализовать полиморфизм. Например, рассмотрим коллекцию объектов, включающую Rectangle и Square. Каждый такой объект имеет свою собственную реализацию метода printArea.

В следующем фрагменте фактический код, который должен быть выполнен выражением [anObject printArea], определяется во время выполнения. Система runtime использует селектор для метода run, чтобы определить подходящий метод в каком бы классе ни оказался anObject.

Звучит сложно? Давайте рассмотрим простой код, который довольно наглядно объясняет динамическое связывание.

#import <Foundation/Foundation.h>

@interface Square:NSObject {
   float area;
}

- (void)calculateAreaOfSide:(CGFloat)side;
- (void)printArea;
@end

@implementation Square
- (void)calculateAreaOfSide:(CGFloat)side {
   area = side * side;
}

- (void)printArea {
   NSLog(@"The area of square is %f",area);
}

@end

@interface Rectangle:NSObject {
   float area;
}

- (void)calculateAreaOfLength:(CGFloat)length andBreadth:(CGFloat)breadth;
- (void)printArea;
@end

@implementation  Rectangle

- (void)calculateAreaOfLength:(CGFloat)length andBreadth:(CGFloat)breadth {
   area = length * breadth;
}

- (void)printArea {
   NSLog(@"The area of Rectangle is %f",area);
}

@end

int main() {
   Square *square = [[Square alloc]init];
   [square calculateAreaOfSide:10.0];
   
   Rectangle *rectangle = [[Rectangle alloc]init];
   [rectangle calculateAreaOfLength:10.0 andBreadth:5.0];
   
   NSArray *shapes = [[NSArray alloc]initWithObjects: square, rectangle,nil];
   id object1 = [shapes objectAtIndex:0];
   [object1 printArea];
   
   id object2 = [shapes objectAtIndex:1];
   [object2 printArea];
   
   return 0;
}

Теперь, когда мы скомпилируем и запустим программу, мы получим следующий результат:

2013-09-28 07:42:29.821 demo[4916] The area of square is 100.000000
2013-09-28 07:42:29.821 demo[4916] The area of Rectangle is 50.000000

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

Подведение итогов

В качестве резюме к этой статье, давайте просто ответим на пять   самых частых вопроса по позднему связыванию.

Как объявить переменную в Objective C?

С помощью ключевого слова extern вы можете объявить переменную в любом месте программы. Хотя вы можете объявлять переменную несколько раз в вашей программе Objective-C, но она может быть определена только один раз в файле, функции или блоке кода.

Когда возникает статическое или динамическое связывание?

Если компилятору удается определить, является ли объект типом «базовый класс» или типом «наследуемый класс» во время компиляции, то вы получаете статическое связывание, в противном случае — динамическое. Поэтому вам понадобится какая-то информация о типе во время выполнения (RTTI).

Как выполняется точный код при динамическом связывании?

Точный выполняемый код определяется как именем метода (селектором), так и принимающим объектом. Динамическое связывание позволяет использовать полиморфизм.

Как выполняется проверка типов при динамическом связывании?

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

В чем разница между динамическим связыванием и динамической типизацией в Objective C?

Динамическая типизация в Objective-C означает, что класс объекта типа id неизвестен во время компиляции, а обнаруживается во время выполнения, когда объекту посылается сообщение.

Останні статті

Что такое прокси-сервер: пояснение простыми словами, зачем нужны прокси

Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…

21.11.2024

Что такое PWA приложение? Зачем необходимо прогрессивное веб-приложение

Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…

19.11.2024

Как создать игру на телефоне: программирование с помощью конструктора

Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…

17.11.2024

Google Bard: эффективный аналог ChatGPT

В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…

14.11.2024

Скрипт и программирование: что это такое простыми словами

Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…

12.11.2024

Дедлайн в разработке: что это такое простыми словами

Дедлайн (от англ. deadline — «крайний срок») — это конечная дата стачи проекта или задачи…

11.11.2024