Не рекомендуется включать файлы реализации, такие как файлы .m (или .c / .cpp). Если вам нужно включить файл, он, вероятно, должен быть .h.
Включая Foo.m, у вас есть две реализации FooClass
, которые не нравятся компоновщику. Это связано с тем, что включение в этот момент похоже на копирование и вставку файла.
В вашем примере компилятор компилирует два файла - main.m и Foo.m, и в обоих есть раздел @implementation
для FooClass
.
У вас должна быть одна реализация между всеми скомпилированными файлами, но вы можете объявить интерфейс любое количество раз, поэтому мы поместили объявление интерфейса в заголовочные файлы.
По этой логике, хотя это и не является соглашением, технически вы можете поместить все в один файл main.m и просто скомпилировать его. Однако ради здравого смысла, когда у вас есть больше кода, вы должны разбить его на файлы класса .h / .m.
Существует еще одна (плохая) опция, позволяющая не использовать заголовки, когда вы добавляете только раздел @interface в файлы, которые будут включать его, но, опять же, я не рекомендую этого, потому что вы пройдете через ад линкер Вы редактируете одну из этих копий и забываете другую. В вашем случае вы просто добавляете раздел FooClass
@interface
в начало файла main.m.