Каковы ваши соглашения об именах для методов 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!) с префиксом, похожим на имя класса. Поэтому я беру буквы верхнего регистра имени класса, чтобы сформировать "частный префикс":
-
ComplexFileParser
→ CFP
-
URLDownloadTask
→ URLDT
-
SessionController
→ SC
Это все еще не совсем безопасно, но маловероятно, что подкласс с другим именем имеет тот же самый частный префикс.
Также, когда вы выполняете фреймворки, вы должны префикс всех классов и других символов с помощью префикса структуры (поскольку Apple делает с NS...
, CF...
, CA...
, SC...
, UI...
и т.д.) и таким образом, этот префикс класса является частью частного префикса, а также делает конфликты еще менее вероятными:
- Рамки
DecodingUtils.framework
→ DU
- Класс
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", префиксы класса или названия проекта - они вообще не используют их. Просто подчеркивает.