Objective-C “私有”的命名约定是什么?方法?

发布于 2024-11-04 04:09:49 字数 1269 浏览 3 评论 0原文

继承其他开发人员的代码使我坚信通过类扩展的方式将尽可能多的消息保留在类的公共接口之外。我还坚信对类的私有、特定于实现的成员采用特殊的命名约定。我真的很喜欢能够一眼看出正在发送的消息以及在实现上下文中引用的哪些成员不适合公共使用,反之亦然。如果不出意外的话,它使我更容易更快地掌握类的整体语义,这是值得的。

撇开理由不谈,我已经编写了大量带有私有方法2的类,但我从未真正想出一种我真正喜欢的命名模式(就像我为有争议的 ivar_ 约定所做的那样)伊瓦尔)。值得注意的例子:

@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

此时,我可以通过多种不同的方式来破坏我的私有方法名称,但我认为我不会编造一些东西,而是首先对我可能不知道的任何流行约定进行民意调查。那么,你用过什么?

Inheriting code from other developers has made me a firm believer in keeping as many messages as possible out of a class' public interface by means of a Class Extension. I'm also a firm believer in adopting special naming conventions for private, implementation-specific members of a class. I really like being able to tell at a glance what messages being sent and what members being referenced within the implementation context are not ever intended for public use and vice versa. If nothing else, it makes the overall semantics of a class easier for me grasp more quickly, and that's worth it.

Justification aside, I've written boatloads of classes with boatloads2 of private methods, but I've never really come up with a pattern for naming that I really love (like I do the controversial ivar_ convention for ivars). Notable examples:

@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

At this point, there are a kajillion different means by which I could mangle my private method names, but instead of making something up, I figured I would first take a poll for any popular conventions I may not be aware of. So, what have you used?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

倾城°AllureLove 2024-11-11 04:09:49

我不通过名称来区分私有方法。相反,我通过在 .m 文件的类扩展部分中声明它们来将它们排除在公共接口之外,因此:

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

I don't distinguish private methods by name. Instead, I keep them out of the public interface by declaring them in the class extension portion of the .m file, thus:

@interface MyClass ()
- (void)doWork;
@end
撕心裂肺的伤痛 2024-11-11 04:09:49

我对我的私有方法使用双下划线:

- (void)__doSomethingPrivate;

它几乎看起来像单下划线语法(可读性好),同时确认了 Apple 指南。

I use double underscore for my private methods:

- (void)__doSomethingPrivate;

It almost looks like the single underscore-syntax (good readable) and at the same time confirms to the Apple guides.

音栖息无 2024-11-11 04:09:49

我使用前缀,没有下划线。前缀通常与相关项目的名称相关。如果您确实使用下划线,则无需使用多个下划线。

I use a prefix, no underscore. The prefix is generally related to the name of the project in question. If you do use underscores, there's no need to have more than one.

-黛色若梦 2024-11-11 04:09:49

我使用两个级别的私有方法:轻微私有和非常私有。轻微私有方法是可以变为公开的方法,但目前还没有。它们通常是我在内部使用的便捷方法,除非我决定将其公开,否则我通常不会提供太多的保护。对于非常私有的方法,我忽略 apple 并使用下划线前缀。由于 99% 的代码都在我创建的类中,并且我的类名通常有前缀,因此遇到命名问题的可能性很小。当向我没有创建的类添加代码时,我很少创建私有方法,但在极少数情况下会添加一个短前缀。

I use two levels of private methods: slightly private and very private. Slightly private methods are methods which could become public, but currently aren't. They are usually convenience methods that I use internally, and I usually don't put in as much protection unless I decide to make it public. For very private methods, I ignore apple and use an underscore prefix. Since 99% of my code is in classes I create and I usually have prefixes on my class names, the chances of running into naming problems is small. When adding code to classes I didn't make, I rarely make private methods, but add a short prefix on the rare occasion that I do.

美人骨 2024-11-11 04:09:49

我在私有方法前加上“p”前缀:

  • (void) pDoWork;
  • (void) pDoWork:(id) 与:(id) 一起工作;

同样,我使用 's' 表示静态(或类)方法:

  • (Universe*)sGet; // 用于返回单例 Universe 对象。

除了命名约定之外,我还在 .m 文件而不是 .h 文件中声明私有方法。

I prefix private methods with a 'p':

  • (void) pDoWork;
  • (void) pDoWork:(id)work with:(id)something;

Similarly, I use 's' for static (or class) methods:

  • (Universe*)sGet; // used to return singleton Universe object.

Beyond naming conventions, I declare private methods in .m files instead of .h files.

北陌 2024-11-11 04:09:49

使用固定前缀将有助于从外界“隐藏”该方法,但它不会阻止方法被意外覆盖。例如,我曾经扩展了一个类并创建了一个方法:

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

结果是该类的行为以可怕的方式破坏了。 但是为什么?事实证明,超类也有一个方法名称private_close,并且我不小心重写了它而没有调用super!我怎么知道?没有编译器警告!

无论您的前缀是 ___pprivate_,如果它始终相同,那么您最终会遇到这样的问题。

因此,我使用类似于类名的前缀为私有方法(和属性!)添加前缀。因此,我采用类名的大写字母来形成“私有前缀”:

  • ComplexFileParser -> CFP
  • URLDownloadTask -> URLDT
  • SessionController -> SC

这仍然不是完全安全的,但具有不同名称的子类不太可能具有相同的私有前缀。

另外,当您创建框架时,您应该为所有类和其他符号添加框架前缀(就像 Apple 的 NS...CF...一样CA...SC...UI... 等),因此该类前缀也是私有前缀的一部分冲突的可能性更小:

  • Framework 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 方法),当然,上面的预处理器技巧不会。

Using a fixed prefix will help to "hide" the method from the outside world but it won't prevent a method from being accidentally overridden. E.g. I once extended a class and I made a method:

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

The result was that the behavior of the class broke in horrible ways. But why? It turned out, the super class also had a method name private_close and I was accidentally overriding it without calling super! How should I know? No compiler warning!

No matter if your prefix is _ or __ or p or private_, if it is always the same, you will end up with problems like this one.

So I prefix private methods (and properties!) with a prefix that resembles the class name. Therefor I take the upper case letters of the class name to form the "private prefix":

  • ComplexFileParser -> CFP
  • URLDownloadTask -> URLDT
  • SessionController -> SC

This is still not perfectly safe, yet it is very unlikely that a subclass with a different name has the same still the same private prefix.

Also when you do frameworks, you should prefix all classes and other symbols with a framework prefix (as Apple does with NS..., CF..., CA..., SC..., UI..., etc.) and thus this class prefix is part of the private prefix as well making collisions even less likely:

  • Framework DecodingUtils.framework -> DU
    • Class ComplexFileDecoder in framework -> DUComplexFileDecoder
      • Private Prefix -> DUCFD
        • Private Method close -> - (void)DUCFD_close

Alternatively append the prefix at the end of the fist method argument name, to get better auto-completion:

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

will become

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

or always only append it to the last parameter name:

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

or (now it gets really crazy) - add a fake dummy parameter just for naming:

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

where x is actually never used in the method and you pass nil for it:

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

and as it will always be the same at the end, use a pre-processor macro:

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

// ...

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

Prefix and suffixing works also with properties (and thus their ivar, getter/setter methods), the preproessor trick above won't, of course.

听,心雨的声音 2024-11-11 04:09:49

关于苹果的建议。您可能对 Apple 如何编写自己的代码感兴趣。

如果你检查私有 API,你会发现它们到处都使用下划线表示私有方法。 iOS 中的所有 Obj-C 代码都使用它们。在许多情况下,这些方法会经历多个 iOS 版本而无需重构或重命名,这意味着这不是它们的临时解决方案,而是一种约定。事实上,他们广泛使用了三个级别的私有方法——无下划线、单下划线和双下划线。

至于其他解决方案,例如“私有”、类或项目名称前缀 - 他们根本不使用它们。只是下划线。

Regarding Apple recommendations. You might be interested in how Apple writes it's own code.

If you check private APIs you will see that they use underscores for private methods everywhere. Every peace of Obj-C code in iOS uses them. And in many cases those methods go through multiple iOS versions without refactoring or renaming which means it's not a temporary solution for them but rather a convention. In fact, there're three levels of private methods they use extensively - no underscore, single and double underscore.

As for other solutions like "private", class or project name prefixes - they don't use them at all. Just underscores.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文