2009-11-08 2 views
4

Я знаю, что Objective-C использует динамическое связывание для всех вызовов методов. Как это реализовано? Объектив-c «превращается в C-код» перед компиляцией и просто использует (void *) указатели на все?Objective-C использует динамическое связывание, но как?

+3

Сценарий объектива-c - это с открытым исходным кодом, кстати. Это делает интересным чтение. objc_msgSend() на самом деле немного сборки, которая делает отправку с помощью оптимизации хвостового вызова, чтобы исключить необходимость перезаписи фрейма стека при вызове. Довольно быстро. – bbum

ответ

11

Концептуально, что происходит в том, что есть диспетчерская библиотека (обычно упоминается как Objective выполнения C), и компилятор преобразует что-то вроде этого:

[myObject myMethodWithArg:a andArg:b ]; 

в

//Not exactly correct, but close enough for this 
objc_msgSend(myObject, "myMethodWithArg:andArg:", a, b); 

И тогда среда выполнения имеет дело со всеми связями и отправкой, находит соответствующую функцию и вызывает ее с этими аргументами. Упрощенно вы можете думать, что это похоже на хэш-поиск; конечно, гораздо сложнее, чем тогда.

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

4

Каждый метод Objective C реализован «под капотом» как (по сути) C-функция. У метода есть связанное с ним сообщение (текстовая строка), а класс имеет таблицу поиска, которая соответствует строке сообщения с помощью функции C. Поэтому, когда вы вызываете метод Objective C, что действительно происходит, вы отправляете строку сообщения объекту, и объект просматривает связанную функцию C в таблице поиска методов своего класса и запускает ее.

Это связано с Objective C тем, как объекты обрабатывают сообщения, которые они не понимают, перенаправляя их, как они кэшируют поиск сообщений и методов и т. Д., Но это основы.

C++ аналогичен, за исключением того, что вместо класса, имеющего таблицу сообщений, он имеет что-то еще, называемое «vtable», и вы вызываете метод не через текстовую строку, а через ее смещение в таблицу vtable. Это форма статической привязки и несколько ускоряет выполнение, но менее гибкая, чем динамическая привязка.