继承其他开发人员的代码使我坚信通过类扩展从类的公共接口中保留尽可能多的消息。我也坚信为类的特定于实现的私有成员采用特殊的命名约定。我真的希望能够一目了然地告诉我们发送的消息以及在实现环境中被引用的成员是不是供公众使用,反之亦然。如果不出意外,它会让我更容易掌握一个班级的整体语义,这是值得的。
除了理由之外,我已经用私人方法编写了大量的课程,但我从来没有真正想出一个我真正喜欢的命名模式(就像我有争议的那样) 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's okay...
- (void)doWork_:(id)work with_:(id)something; // That's 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
在这一点上,有一种不同的手段可以破坏我的私人方法名称,但我没有做出任何事情,我想我会首先对我可能不知道的任何流行惯例进行民意调查。那么,你用过什么?
答案 0 :(得分:9)
我没有按名称区分私人方法。相反,我通过在.m文件的类扩展部分声明它们来使它们脱离公共接口,因此:
@interface MyClass ()
- (void)doWork;
@end
答案 1 :(得分:7)
我的私有方法使用双下划线:
- (void)__doSomethingPrivate;
它几乎看起来像单个下划线语法(良好的可读性),同时向Apple指南确认。
答案 2 :(得分:4)
我使用前缀,没有下划线。前缀通常与相关项目的名称相关。如果你使用下划线,则不需要有多个。
答案 3 :(得分:3)
我使用两个级别的私有方法:略微私有和非常私有。稍微私有的方法是可以公开的方法,但目前不是。它们通常是我在内部使用的方便方法,除非我决定公开,否则我通常不会提供太多保护。对于非常私密的方法,我忽略了apple并使用下划线前缀。由于99%的代码都在我创建的类中,并且我的类名通常都有前缀,因此遇到命名问题的可能性很小。将代码添加到我没有创建的类时,我很少使用私有方法,但在极少数情况下添加一个简短的前缀。
答案 4 :(得分:1)
我在私有方法前加上'p':
类似地,我将's'用于静态(或类)方法:
除了命名约定之外,我在.m文件中声明私有方法而不是.h文件。
答案 5 :(得分:1)
使用固定前缀有助于隐藏"来自外部世界的方法,但它不会阻止方法被意外覆盖。例如。我曾经扩展过一个课程,然后我做了一个方法:
- (void)private_close
{
// ...
}
结果是班级的行为以可怕的方式破裂。 但是为什么?事实证明,超类也有一个方法名称private_close
和我不小心覆盖了它而没有调用超级!我怎么知道?没有编译器警告!
无论您的前缀是_
还是__
还是p
还是private_
,如果它始终相同,您最终会遇到类似这样的问题。
因此,我使用类似于类名的前缀为私有方法(和属性!)添加前缀。因此,我使用类名的大写字母来形成"私有前缀":
ComplexFileParser
- > CFP
URLDownloadTask
- > URLDT
SessionController
- > SC
这仍然不是很安全,但具有不同名称的子类不太可能具有相同的私有前缀。
当你做框架时,你应该在所有类和其他符号前面加上框架前缀(正如Apple对NS...
,CF...
,CA...
,SC...
所做的那样, UI...
等等,因此这个类前缀是私有前缀的一部分,并且更不可能发生冲突:
DecodingUtils.framework
- > DU
ComplexFileDecoder
类 - > DUComplexFileDecoder
DUCFD
- (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];
前缀和后缀也适用于属性(因此也适用于他们的ivar,getter / setter方法),当然,上面的前导技巧也是如此。
答案 6 :(得分:0)
关于Apple的建议。您可能对Apple如何编写自己的代码感兴趣。
如果您检查私有API,您会看到他们在任何地方都使用下划线作为私有方法。 iOS中每个Obj-C代码的和平使用它们。在许多情况下,这些方法通过多个iOS版本而无需重构或重命名,这意味着它不是一个临时解决方案,而是一个约定。实际上,他们广泛使用的是三种级别的私有方法 - 没有下划线,单下和双下划线。
至于其他解决方案,如“私人”,类或项目名称前缀 - 他们根本不使用它们。只是强调。