Каковы ваши соглашения об именах для методов Objective-C "private"?

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

Оправдание в стороне, я написал лодку классов с лодками 2 частных методов, но у меня никогда не возникало шаблона для наименования, которое я действительно люблю (например, я занимаюсь спорным ivar_ для ivars). Известные примеры:

@interface myClass()

// I like this, but as we all know, Apple has dibs on this one, 
// and method name collisions are nasty.
- (void)_myPrivateMessage;

// The suffix version promoted by Google for ivars doesn't really translate
// well to method names in Objective-C, because of the way the method
// signature can be broken into several parts.
- (void)doWork_; // That okay...
- (void)doWork_:(id)work with_:(id)something; // That just ugly and tedious...
- (void)doWork_:(id)work with_:(id)something and_:(id)another; // My eyes...

// This version is suggested by Apple, and has the benefit of being officially 
// recommended. Alas, I don't like it: The capital letter is ugly. I don't like 
// underscores in the middle of the name. Worst of all, I have to type three characters 
// before code-sense does anything more useful than inform me that I am typing.
- (void)BF_doWork;

@end

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

Ответы

Ответ 1

Я использую два уровня частных методов: немного закрытый и очень закрытый. Немногие частные методы - это методы, которые могут стать общедоступными, но в настоящее время их нет. Обычно это методы удобства, которые я использую внутри себя, и обычно я не защищаю их, если не решит сделать их общедоступными. Для очень частных методов я игнорирую яблоко и использую префикс подчеркивания. Поскольку 99% моего кода находится в классах, которые я создаю, и у меня обычно есть префиксы в именах моих классов, вероятность запуска проблем с именами небольшая. При добавлении кода в классы, которые я не делал, я редко делаю частные методы, но добавляю короткий префикс в тот редкий случай, который я делаю.

Ответ 2

Я не различаю частные методы по имени. Вместо этого я оставляю их вне публичного интерфейса, объявляя их в части расширения класса файла .m, таким образом:

@interface MyClass ()
- (void)doWork;
@end

Ответ 3

Я использую двойное подчеркивание для своих личных методов:

- (void)__doSomethingPrivate;

Он почти похож на единственный синтаксис подчеркивания (хорошо читаемый) и в то же время подтверждает руководство Apple.

Ответ 4

Я использую префикс, не подчеркивая. Префикс обычно связан с именем рассматриваемого проекта. Если вы используете символы подчеркивания, нет необходимости иметь больше одного.

Ответ 5

Я префикс private методов с помощью 'p':

  • (void) pDoWork;
  • (void) pDoWork: (id) работает с: (id) что-то;

Аналогично, я использую 's' для статических (или классных) методов:

  • (Universe *) SGET;//используется для возврата объекта singleton Universe.

Помимо соглашений об именах, я объявляю частные методы в файлах .m вместо файлов .h.

Ответ 6

Использование фиксированного префикса поможет "скрыть" метод из внешнего мира, но это не помешает случайному переопределению метода. Например. Я однажды расширил класс, и я сделал метод:

- (void)private_close
{
    // ...
}

В результате поведение класса сломалось ужасно. Но почему? Оказалось, что суперкласс также имел имя метода private_close, и я случайно переопределял его без вызова супер! Как я должен знать? Предупреждение о компиляторе!

Независимо от того, имеет ли ваш префикс _ или __ или p или private_, если он всегда один и тот же, у вас возникнут проблемы, подобные этому.

Итак, я префикс private methods (и properties!) с префиксом, похожим на имя класса. Поэтому я беру буквы верхнего регистра имени класса, чтобы сформировать "частный префикс":

  • ComplexFileParserCFP
  • URLDownloadTaskURLDT
  • SessionControllerSC

Это все еще не совсем безопасно, но маловероятно, что подкласс с другим именем имеет тот же самый частный префикс.

Также, когда вы выполняете фреймворки, вы должны префикс всех классов и других символов с помощью префикса структуры (поскольку Apple делает с NS..., CF..., CA..., SC..., UI... и т.д.) и таким образом, этот префикс класса является частью частного префикса, а также делает конфликты еще менее вероятными:

  • Рамки DecodingUtils.frameworkDU
    • Класс ComplexFileDecoder в рамках → DUComplexFileDecoder
      • Частный префикс → DUCFD
        • Закрытый метод close → - (void)DUCFD_close

Альтернативно добавьте префикс в конце имени аргумента метода кулака, чтобы получить лучшее автозаполнение:

- (void)doSomethingWith:(Type1)var1 parameters:(Type2)var2

станет

- (void)doSomethingWith_DUCFD:(Type1)var1 parameters:(Type2)var2

или всегда добавляйте его только к последнему имени параметра:

- (void)doSomethingWith:(Type1)var1 parameters_DUCFD:(Type2)var2

или (теперь он становится действительно сумасшедшим) - добавьте поддельный параметр фиктивного кода только для именования:

- (void)doSomethingWith:(Type1)var1 parameters:(Type2)var2 DUCFD:(id)x

где x на самом деле никогда не используется в методе, и вы передаете nil для него:

[self doSomethingWith:var1 parameters:var2 DUCFD:nil];

и поскольку он всегда будет таким же в конце, используйте макропроцессор:

#define priv DUCFD:nil
#define PRIVATE DUCFD:nil

// ...

[self doSomethingWith:var1 parameters:var2 priv];
[self doSomethingWith:var1 parameters:var2 PRIVATE];

Префикс и суффикс работают также со свойствами (и, следовательно, с их иварами, методами getter/setter), трюк preproessor выше не будет, конечно.

Ответ 7

Относительно рекомендаций Apple. Вам может быть интересно, как Apple пишет собственный код.

Если вы проверите частные API-интерфейсы, вы увидите, что они используют символы подчеркивания для личных методов везде. Каждый мир кода Obj-C в iOS их использует. И во многих случаях эти методы проходят через несколько версий iOS без рефакторинга или переименования, что означает, что это не временное решение для них, а скорее соглашение. Фактически, есть три уровня частных методов, которые они используют широко - не подчеркивание, однократное и двойное подчеркивание.

Что касается других решений, таких как "private", префиксы класса или названия проекта - они вообще не используют их. Просто подчеркивает.