Cocoa 类别命名约定的最佳实践
我正在整理我古老的 Cocoa 代码以使用现代命名约定。关于最佳实践已有很多讨论,但我不确定一件事。
我正在考虑为类别方法名称添加前缀,以确保唯一性。人们似乎普遍认为这是一个好主意,尽管大多数人可能不会打扰。
我的问题是:像 -copyDeep
这样进行深层复制的 NSDictionary
类别方法怎么样?该方法曾经被命名为 -deepCopy
,但当分析器查找“copy”前缀时,我颠倒了这些词。因此我大概无法添加前缀。并且在方法名称的中间或末尾添加“前缀”看起来很混乱且不一致。
我也对前缀样式的想法感兴趣 - 我目前使用 DS
(对于 Dejal Systems)作为类前缀。但我知道Apple现在想为自己保留所有两个字符的前缀,所以我正在考虑使用Dejal
,例如我的类DSManagedObject
将被重命名为DejalManagedObject
。回到类别,他们的方法将被重命名以添加 dejal
前缀,例如从 -substringFromString:
到 -dejalSubstringFromString:
。但是 -dejalCopyDeep
会让分析器感到困惑,所以也许我必须对这些方法不一致,并使用 -copyDeepDejal
或 -copyDeep_dejal
?
一旦我清理了我的类别和各种类,我将重新发布它们作为开源,因此遵循最新的约定将是有益的。
I am tidying up my ancient Cocoa code to use modern naming conventions. There has been lots of discussion on best practices, but I'm unsure of one thing.
I'm thinking about adding a prefix to category method names, to ensure uniqueness. It seem generally agreed that this is a good idea, though most people probably don't bother.
My question is: what about a NSDictionary
category method like -copyDeep
that does a deep copy? The method used to be named -deepCopy
, but I reversed the words as the analyzer looks for a prefix of "copy". Therefore I presumably couldn't add a prefix. And having the "prefix" in the middle or end of the method name seems messy and inconsistent.
I'd also be interested in thoughts on the style of prefix -- I currently use DS
(for Dejal Systems) for class prefixes. But I know that Apple now wants to reserve all two-character prefixes for themselves, so am thinking about using Dejal
, e.g. my class DSManagedObject
would be renamed as DejalManagedObject
. And getting back to categories, their methods would be renamed to add a dejal
prefix, e.g. from -substringFromString:
to -dejalSubstringFromString:
. But -dejalCopyDeep
would confuse the analyzer, so maybe I'd have to be inconsistent for such methods, and use -copyDeepDejal
or -copyDeep_dejal
?
I will be re-releasing my categories and various classes as open source once I've cleaned them up, so following the latest conventions will be beneficial.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我向 Apple 应用程序框架布道者发送了有关此问题的电子邮件,并收到了建议不要为类别方法名称添加前缀的回复。这与前述 WWDC10 会议中的建议相冲突,但我认为反映了苹果当前的想法。
他建议只查看 beta 种子 API 差异来发现冲突,这也是我一直在做的事情。
I emailed the Apple Application Frameworks Evangelist about this, and got a reply that recommended not prefixing category method names. Which conflicts with the advice in the aforelinked WWDC10 session, but I assume reflects Apple's current thinking.
He recommended just looking at the beta seed API diffs to spot conflicts, which is what I've always been doing.
我同意 Kevin Ballard 的观点,您应该为类别方法名称添加前缀,特别是如果您要将它们分发给其他人。但您确实有理由担心分析器会被
DScopy
混淆。如果 DScopy 的定义/实现是在没有 ARC 的情况下完成的,并且被另一个使用 ARC 的类使用(反之亦然),那么 ARC 编译器也会同样感到困惑。我的首选解决方案是使用“所有权转移注释”,例如:
它们将用于覆盖编译器读取方法名称并对其进行操作的默认行为。您可以像这样声明
DScopy
:(此声明必须位于由所有使用此方法的类导入的头文件中,由于链接而提到)的源代码>NS_RETURNS...
WWDC 2011 第 322 场会议 - Objective-C 深入进展。本期的正文大约在 9 点 10 分开始。关于“但我知道苹果现在想为自己保留所有两字符前缀”的注释。作为个人喜好,我喜欢使用
_
字符来分隔前缀和名称,它对我来说效果很好。您可以尝试类似的操作:这将为您提供三个字符,并且可以说使方法名称更具可读性。
编辑响应评论中发布的链接。
然而,正如贾斯汀对你原来问题的回答所说,这是可以打破的。
关于属性;我不建议使用
__attribute__((objc_method_family(copy)))
我建议使用NS_RETURNS_RETAINED
,它翻译为:__attribute__((ns_returns_retained))
。虽然第一个示例甚至不会使用- (NSString *)string __attribute__((objc_method_family(copy)));
进行编译(正如他所说),但它会使用- (NSString *) 进行编译细绳; NS_RETURNS_RETAINED;
就好了。显然,如果
NS_RETURNS_..
在单独的.m
中对编译器“隐藏”或以其他方式间接,并且编译器无法看到指令这是行不通的。因此,我建议将任何可能导致分析器/编译器混淆的方法的声明放在主.h
文件(导入所有其他文件的文件)中,以限制出现这种情况的可能性一个问题。I agree with Kevin Ballard, you should prefix your category method names, particularly if you are going to distribute them to others. But you do have a valid concern the analyzer will be confused by
DScopy
. The ARC compiler will similarly be confused if the definition/implementation ofDScopy
is done without ARC and is used by another class using ARC (or vice versa).My preferred solution is to use "ownership transfer annotations", such as:
They would be used to override the compilers default behavior of reading method names and acting on them. You might declare
DScopy
like so: (This declaration must be in a header file that is imported by all the classes that use this method mentioned due to link)Source for
NS_RETURNS...
WWDC 2011 Session 322 - Objective-C Advancements in Depth. The meat of this issue begins at about time 9:10.A note about "But I know that Apple now wants to reserve all two-character prefixes for themselves". As a personal preference I like to use the
_
character to separate the prefix from the name, it works well for me. You might try something like:This would give you three characters, and arguably make the method name more readable.
Edit In response to link posted in comment.
However as Justin's answer to your original question says that can be broken.
With regards to attributes; I did not suggest using
__attribute__((objc_method_family(copy)))
I suggested usingNS_RETURNS_RETAINED
, which translates to :__attribute__((ns_returns_retained))
. While the first example there won't even compile (as he says) using- (NSString *)string __attribute__((objc_method_family(copy)));
it compiles with- (NSString *)string; NS_RETURNS_RETAINED;
just fine.Obviously also if the
NS_RETURNS_..
are "hidden" from the compiler in separate the.m
s or indirected in some other way and the compiler can't see the directives then it won't work. Because of this I would suggest putting the declaration for any methods that may cause the analyzer/compiler confusion in your main.h
file (the one that imports all the others) to limit the chances that there will be an issue.