Разница между объявлением протоколов в открытом интерфейсе и частным интерфейсом/файлом реализации

В чем заключаются различия между объявлением этих протоколов? Это просто, что файлы в файле .h являются общедоступными?

in .h file:
@interface TestViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>

in .m file:
@interface TestViewController () <UISearchBarDelegate, UISearchDisplayDelegate, UIAlertViewDelegate, MKMapViewDelegate, CLLocationManagerDelegate>

Ответы

Ответ 1

Когда вы добавляете протоколы в файл .h, это говорит всем, что включает заголовочный файл, который класс придерживается в данных протоколах.

Когда вы добавляете протоколы в файл .m, это, по сути, частный признак того, что класс придерживается протоколов. Только реализация знает.

Вы должны использовать только первую форму (в файле .h), когда внешние классы должны знать, что класс придерживается протокола. Вы должны использовать вторую форму (в .m файле), когда заботится только об осуществлении.

В приведенном вами примере маловероятно, чтобы другие классы знали о классе, придерживающемся протоколов табличного представления. Они должны быть в файле .m. Также маловероятно, чтобы любой другой класс знал о протоколах поиска. Это детали реализации. Они принадлежат файлу .m.

Могут быть случаи, когда вы используете оба. Это нормально.

Вот мое руководство. Поместите его в файл .m, если у вас нет необходимости сообщать другим классам об использовании протокола.

Ответ 2

Если я ошибаюсь, невозможно использовать форвардное объявление @protocol Foo;, если вы также заявляете, что ваш класс принимает протокол.

Это означает, что в заголовочном файле вашего класса вам необходимо включить/импортировать другой заголовочный файл с объявлением протокола. В зависимости от размера и сложности проекта это может привести к тому, что файл заголовка "адский ад".

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

Ответ 3

Я признаю, что это не может быть вопросом стиля!!!

Зачем скрывать эти протоколы в .m, возможно, ваши классы будут работать с некоторыми фреймворками. Там .h видно, и каждый может видеть "Oh yaaa, это протоколы делегатов для этого класса". Вместо скрытой магии.

Итак, он сделан прозрачным, а не непрозрачным.

Ответ 4

Я считаю предпочтительным первый способ, так что кто использует класс, знает, реализует ли класс какой-то протокол. Это может быть только преимуществом.

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

Он также закрывает некоторые предупреждения компилятора для функций (или методов), подобных этим:

void foo(id< SomeProtocol> obj) {...}

Прозрачность часто является хорошей идеей и редко является недостатком.