после импорта '.h' в файл '.m' они навсегда связаны? - PullRequest
0 голосов
/ 12 февраля 2011

У меня есть CarClass.h файл, который объявляет CarClass.
Затем я #import этот CarClass.h файл помещаю в мой CarClass.m файл, где я, конечно, затем продолжаю реализовывать все мои CarClass методы..
Наконец, мой CarAPP.m файл (который содержит main) ТАКЖЕ #imports CarClass.h - и все работает просто отлично.

Ss там на самом деле нет проблем: -)

Тем не менее, я не уверен, что понимаю, ПОЧЕМУ это работает - потому что связь кажется немного неработающей: если CarAPP.m импортирует ТОЛЬКО файл CarClass.h - без импорта файла CarClass.m, то где жеПОЛУЧИТЬ или ВИДЕТЬ реализации?Это тот случай, когда после компиляции файла «.m», который импортирует файл «.h», эти два файла (.h и .m) будут связаны навсегда или что-то в этом роде?Я просто не понимаю ...

Ответы [ 2 ]

1 голос
/ 12 февраля 2011

Процесс компиляции разбивается на разные фазы, и директивы #import интерпретируются задолго до того, как произойдет какая-либо связь.

Когда вы передаете файлы кода (.c, .m) вашему компилятору, он будет пытаться сгенерировать из него файл объекта кода (.o); это двоичное представление вашего кода. Этот файл еще не исполняется, потому что ему нужно больше информации. Особенно, это не связано ни с каким другим файлом. Заголовочные файлы, которые должны содержать только объявления и без определений, как правило, не получают свой собственный соответствующий файл .o.

После того, как все ваши файлы кода были превращены в объекты кода, компилятор соединит их все вместе и вызовет компоновщик. Компоновщик разрешит все внешние ссылки, а затем создаст исполняемый файл.

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

Поскольку все ваши объектные файлы кода упакованы вместе, вся ваша программа получает доступ ко всему, что было публично объявлено внутри себя. Вот почему вам не нужно явно «связывать» CarAPP.m с CarClass.m.

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

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

Если у вас есть #import whatEver.h, препроцессор пытается найти соответствующий файл в расположении по умолчанию. Если он найден, он просто вставляет содержимое whatEver.h в соответствующий исходный файл, где бы вы ни использовали #import whatEver.h. Итак, чтобы получить финальный исполняемый файл, ваши исходные файлы должны пройти этапы Pre-Process, Compile и Linker.

Когда у вас есть CarClass.h в CarAPP.m, компоновщик отправляется на поиск реализаций CarClass.h в CarClass.m. Строго говоря, речь идет о том, чтобы найти определения в CarClass.o. Компилятор счастлив, если есть объявления о том, что вы используете, и компоновщик счастлив, если есть определения для объявлений, которые вы собираетесь использовать.

Когда вы импортируете CarClass.h в CarAPP.m, вы говорите компоновщику, чтобы он нашел реализации метода CarClass.h в CarClass.o. Итак, ваш окончательный исполняемый файл представляет собой комбинацию CarAPP.o и CarClass.o. Чтобы больше узнать о том, как выполняется компиляция и компоновка, Компиляция программы . Хотя ссылка специфична для C / C ++, она должна дать вам представление.

...