Позднее связывание против динамического связывания - PullRequest
3 голосов
/ 10 мая 2011

Я везде читал, что Objective-C имеет истинное динамическое связывание, тогда как в C ++ только позднее связывание. К сожалению, ни одна из книг не объясняет это ясно и не обсуждает основную реализацию. Например, C ++ использует виртуальную таблицу. Как насчет Objective-C?

Ответы [ 2 ]

8 голосов
/ 10 мая 2011

http://www.gnu.org/software/gnustep/resources/ObjCFun.html имеет довольно хорошее описание.

По сути, динамическое связывание означает, что во время фактического вызова метода принимается решение о том, какой метод вызывать.И метод, если вы хотите, может быть выбран динамически в этот момент.

Редактировать : Здесь гораздо больше подробностей, насколько я понимаю.Я не обещаю, что это совершенно правильно, но это должно быть в основном правильно.Каждый объект в Objective C - это структура, первый член которой с именем isa является указателем на класс.Каждый класс сам по себе является объектом, который традиционно выглядит следующим образом:

struct objc_class {
    Class isa;
    Class super_class;
    const char *name;
    long version;
    long info;
    long instance_size;
    struct objc_ivar_list *ivars;
    struct objc_method_list **methodLists;
    struct objc_cache *cache;
    struct objc_protocol_list *protocols;
};

Во время выполнения приведен псевдокод того, что происходит при поиске метода:

Follow isa to find the class
if implementation = class.lookup_method(method):
    call implementation
else if get_implementation = class.lookup_method(forwardInvocation):
    implementation = get_implementation(method)
    if implementation:
        call implementation
    else:
       raise runtime error
else:
    raise runtime error

И какчто lookup_method работает?

def lookup_method (class, method):
    if method in class.objc_cache:
        return implementation from objc_cache
    else if method in class.objc_method_list:
        cache implementation from objc_method_list
        return implementation
    else if implementation = class.super_class.lookup_method(method):
        cache implementation
        return implementation
    else:
        return null

В ответ на очевидный вопрос, да, это намного медленнее, чем виртуальные таблицы C ++.По оценкам, около 1/3 скорости.Из каждого текста Objective C сразу же следует, что в реальном мире скорость поиска метода почти никогда не является узким местом.

Это гораздо более гибко, чем поиск метода Си.Например, вы можете использовать forwardInvocation, чтобы заставить нераспознанные методы перейти к объекту, который есть в переменной.Такое делегирование может быть выполнено без знания типа этого объекта во время выполнения или методов, которые он будет поддерживать.Вы также можете добавлять методы к классам - даже во время выполнения, если хотите - без доступа к исходному коду.У вас также есть богатый внутренний анализ времени выполнения для классов и методов.

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

Это объясняет различия и дает вам достаточно деталей, чтобы понять, что происходит?

0 голосов
/ 12 февраля 2014

И динамическое, и позднее связывание фактически одинаковы.У нас есть статическая привязка или ранняя привязка, которая проверяет проблемы, возникающие во время компиляции (ошибки, связанные с переменными, выражениями и т. Д.), И эта информация хранится в v-таблице (таблица виртуальных методов).Что делает позднее связывание, так это то, что оно просто связывает методы с методами в v-таблице.

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