kzen.dev
  • Вопросы
  • Метки
  • Пользователи
Оповещения
Вознаграждения
Регистрация
После регистрации, сможете получать уведомления об ответах и комментариях на Ваши вопросы.
Вход
Если у Вас уже есть аккаунт, войдите чтобы проверить новые уведомления.
Тут будут вознаграждения за добавленные вопросы, ответы и комментарий.
Дополнительно
Источник
Редактировать
Clinton Blackmore
Clinton Blackmore
Вопрос

Когда определять объективные методы?

Я изучаю Objective-C и имею опыт работы с C/C++.

  • В объектно-ориентированном C++ всегда нужно объявлять метод до его определения (реализации), даже если он объявлен в родительском классе.

  • В процедурном C, IIRC, вы можете обойтись простым определением функции до тех пор, пока она вызывается из чего-то другого в той же единице компиляции (т.е. из того же файла), которая появилась позже в файле (ну, при условии, что вы не объявили ее в другом месте с помощью "extern").

  • Теперь, в Objective-C, похоже, что вам нужно объявлять селекторы в заголовочном файле, только если они будут использоваться чем-то внешним, и что вы можете создавать селекторы в вашем .m файле и вызывать их внутри .m файла. Также, похоже, что методы делегата или наследуемые методы никогда не определяются (повторно).

Нахожусь ли я на правильном пути? Когда вам нужно определить селектор в Objective-C?

34 2009-06-19T21:21:24+00:00 3
Quinn Taylor
Quinn Taylor
Редактировал вопрос 6-го июля 2009 в 6:19
Программирование
definition
objective-c
api-design
declaration
Решение / Ответ
Quinn Taylor
Quinn Taylor
19-го июня 2009 в 10:32
2009-06-19T22:32:04+00:00
Дополнительно
Источник
Редактировать
#9181237

Для методов Objective-C общепринятой практикой является размещение методов, которые вы хотите раскрыть, в секции @interface заголовочного файла, чтобы другой код мог включать только .h и знать, как взаимодействовать с вашим кодом. Основанное на порядке "ленивое объявление" работает так же, как функции в C - вы не обязаны **объявлять прототип метода, если у вас нет зависимости, которая не может быть разрешена упорядочиванием, но вы можете добавить прототипы методов внутри @implementation, если это необходимо.

Так что да, вы на правильном пути. Не повторяйте прототип метода для наследуемых методов - компилятор найдет его в заголовочном файле родителя. Методы делегата могут быть определены как прототипы в категории (прикреплены к классу) и реализованы по желанию, но делегату не нужно предоставлять прототип метода, поскольку он уже определен. (Он все еще может это сделать, если хочет, для ясности и т.д.)

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


Когда вы статически типизируете переменную (например, MyClass* вместо id), компилятор предупредит вас, когда вы попытаетесь вызвать метод, о котором класс не сообщает, что он его реализует, независимо от того, реализует он его или нет. Если вы динамически введете переменную, компилятор не помешает вам вызывать все, что вам нравится, и вы получите только ошибки времени выполнения, если вызовете что-то, чего не существует. Что касается языка, вы можете вызывать любой метод, который реализует класс, без ошибок во время выполнения - нет никакого способа ограничить, кто может вызывать метод.

Лично я считаю, что это даже хорошо. Мы так привыкли к инкапсуляции и защите своего кода от другого кода, что иногда относимся к вызывающему методу как к коварному злоумышленнику, а не как к надежному коллеге или клиенту. Я нахожу, что довольно приятно писать код с мышлением "ты делаешь свою работу, а я свою", где каждый уважает границы и занимается своим делом. Можно сказать, что "отношение" Objective-C - это скорее доверие сообщества, чем строгое соблюдение. Например, я с радостью помогу любому, кто придет ко мне на работу, но буду очень раздражен, если кто-то испортит мои вещи или переставит их без спроса. Хорошо продуманный код не обязательно должен быть параноидальным или социопатическим, он просто должен хорошо работать вместе. :-)

Тем не менее, существует множество подходов к структурированию интерфейсов, в зависимости от того, какой уровень детализации вы хотите/необходим в раскрытии интерфейсов для пользователей. Любые методы, которые вы объявляете в заголовке public, по сути, являются честной игрой для любого пользователя. Скрытие деклараций методов сродни запиранию машины или дома - это, вероятно, не позволит всем проникнуть внутрь, но (1) это "держит честных людей честными", не искушая их тем, с чем они не должны связываться, и (2) любой, кто делает вход, наверняка знает, что не должен был этого делать, и не может пожаловаться на негативные последствия.

Ниже приведены некоторые соглашения, которые я использую для именования файлов, и что входит в каждый файл - начиная с файла .m в самом низу, каждый файл включает в себя предыдущий. (Использование строгой цепочки включения предотвращает такие вещи, как предупреждения о дублировании символов). Некоторые из этих уровней применимы только к большим многократно используемым компонентам, таким как фреймворки Cocoa. Адаптируйте их в соответствии с вашими потребностями и используйте любые подходящие вам имена.

  • MyClass.h - общедоступный API (интерфейс прикладного программирования)
  • MyClass_Private.h - Внутренний интерфейс SPI (интерфейс системного программирования)
  • MyClass_Internal.h - Внутренний IPI (Внутренний интерфейс программирования) проекта
  • MyClass.m - Реализация, в целом все объявления API/SPI/IPI
  • MyClass_Foo.m - Дополнительная реализация, например, для категорий

API предназначен для использования всеми и поддерживается публично (обычно в Foo.framework/Headers). SPI раскрывает дополнительную функциональность для внутренних клиентов вашего кода, но с пониманием того, что поддержка может быть ограничена и интерфейс может быть изменен (обычно в Foo.framework/PrivateHeaders). IPI состоит из специфических для реализации деталей, которые никогда не должны использоваться за пределами самого проекта, и эти заголовки вообще не включены во фреймворк. Любой, кто решит использовать вызовы SPI и IPI, делает это на свой страх и риск и, как правило, во вред себе, когда изменения ломают его код. :-)

Quinn Taylor
Quinn Taylor
Редактировал ответ 20-го июня 2009 в 5:11
78
0
 Abizern
Abizern
19-го июня 2009 в 9:31
2009-06-19T21:31:36+00:00
Дополнительно
Источник
Редактировать
#9181235

Объявление методов в заголовочном файле только остановит предупреждения компилятора. Objective-C - динамический язык, поэтому вы можете вызвать метод (отправить сообщение) объекту независимо от того, объявлен этот метод снаружи или нет.

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

Конечно, это означает, что в Objective-C не существует приватных методов. Любой метод, который реализует класс, может быть вызван.

Личное предпочтение. Если это публичный метод (т.е. используемый извне), объявите его в .h и определите в .m. Если вы хотите ограничить его видимость или хотя бы указать, что это приватный метод, используйте categories/class extensions в файле .m. Хотя во многих примерах кода используется метод ленивого объявления.

 Community
Community
Редактировал ответ 23-го мая 2017 в 10:28
6
0
 LBushkin
LBushkin
19-го июня 2009 в 9:36
2009-06-19T21:36:07+00:00
Дополнительно
Источник
Редактировать
#9181236

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

Это может быть очень мощным, но является источником путаницы для новых программистов Obj-C - особенно для тех, кто пришел из C++, Java или C#. Вот основные эмпирические правила:

  • Вы должны определить все публичные методы в вашем @интерфейсе, чтобы потребители знали, какие сообщения вы собираетесь обрабатывать.
  • Вы должны определить @private методы в @интерфейсе, чтобы избежать сообщений компилятора и упорядочить методы в вашей @реализации.
  • Вы должны использовать протоколы при реализации определенной конвенции методов для вашего класса.

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

3
0
Добавить вопрос
Категории
Все
Технологий
Культура / Отдых
Жизнь / Искусство
Наука
Профессии
Бизнес
Пользователи
Все
Новые
Популярные
1
Ilya Smirnov
Зарегистрирован 6 дней назад
2
Денис Васьков
Зарегистрирован 1 неделю назад
3
Dima Patrushev
Зарегистрирован 1 неделю назад
4
sirojidddin otaboyev
Зарегистрирован 2 недели назад
5
Елена Гайдамамакинат
Зарегистрирован 2 недели назад
KO
RU
© kzen.dev 2023
Источник
stackoverflow.com
под лицензией cc by-sa 3.0 с атрибуцией