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

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 неизвестен во время компиляции, а обнаруживается во время выполнения, когда объекту посылается сообщение.

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

Обучение Power BI – какие онлайн курсы аналитики выбрать

Сегодня мы поговорим о том, как выбрать лучшие курсы Power BI в Украине, особенно для…

13.01.2024

Work.ua назвал самые конкурентные вакансии в IТ за 2023 год

В 2023 году во всех крупнейших регионах конкуренция за вакансию выросла на 5–12%. Не исключением…

08.12.2023

Украинская IT-рекрутерка создала бесплатный трекер поиска работы

Unicorn Hunter/Talent Manager Лина Калиш создала бесплатный трекер поиска работы в Notion, систематизирующий все этапы…

07.12.2023

Mate academy отправит работников в 10-дневный оплачиваемый отпуск

Edtech-стартап Mate academy принял решение отправить своих работников в десятидневный отпуск – с 25 декабря…

07.12.2023

Переписки, фото, история браузера: киевский программист зарабатывал на шпионаже

Служба безопасности Украины задержала в Киеве 46-летнего программиста, который за деньги устанавливал шпионские программы и…

07.12.2023

Как вырасти до сеньйора? Девелопер создал популярную подборку на Github

IT-специалист Джордан Катлер создал и выложил на Github подборку разнообразных ресурсов, которые помогут достичь уровня…

07.12.2023