Когда я определяю методы objective-c?

Я изучаю Objective-C и имею фон C/С++.

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

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

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

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

Ответ 1

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

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

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


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

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

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

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

  • 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, делает это на свой страх и риск и обычно в ущерб, когда изменения нарушают их код.: -)

Ответ 2

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

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

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

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

Ответ 3

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

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

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

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