我正在整理古老的Cocoa代码以使用现代命名约定。关于最佳实践的讨论很多,但我不确定一件事。
我正在考虑为类别方法名称添加前缀,以确保唯一性。看起来普遍认为这是一个好主意,尽管大多数人可能都不会打扰。
我的问题是:像NSDictionary
这样的-copyDeep
类别方法可以执行深层复制吗?该方法曾被命名为-deepCopy
,但是当分析器查找“copy”前缀时,我颠倒了这些单词。因此我可能无法添加前缀。在方法名称的中间或末尾加上“前缀”似乎很麻烦且不一致。
我也对前缀样式的想法感兴趣 - 我目前使用DS
(对于Dejal Systems)来获取类前缀。但我知道Apple现在想为自己保留所有双字符前缀,所以我在考虑使用Dejal
,例如我的班级DSManagedObject
将重命名为DejalManagedObject
。回到类别后,他们的方法将被重命名为添加dejal
前缀,例如从-substringFromString:
到-dejalSubstringFromString:
。但是-dejalCopyDeep
会混淆分析器,所以也许我不得不对这些方法不一致,并使用-copyDeepDejal
或-copyDeep_dejal
?
一旦我清理了我的类别和各种类,我将重新发布它们,因此遵循最新的约定将是有益的。
答案 0 :(得分:2)
我通过电子邮件向Apple Application Frameworks Evangelist发送了关于此问题的回复,并得到了一个回复,建议不为类别方法名称添加前缀。这与上述WWDC10会议中的建议相冲突,但我认为这反映了Apple目前的想法。
他建议只关注beta种子API差异来发现冲突,这是我一直在做的事情。
答案 1 :(得分:1)
我同意Kevin Ballard,您应该在类别方法名称前加上前缀,特别是如果您要将它们分发给其他人。但你确实有一个有效的担忧,分析师会被DScopy
混淆。如果DScopy
的定义/实现在没有ARC的情况下完成并且被另一个使用ARC的类(或反之亦然)使用,则ARC编译器同样会感到困惑。
我首选的解决方案是使用“所有权转移注释”,例如:
NS_RETURNS_NOT_RETAINED
NS_RETURNS_RETAINED
它们将用于覆盖编译器读取方法名称并对其进行操作的默认行为。您可以这样声明DScopy
:( 此声明必须位于由于链接而提及的所有使用此方法的类导入的头文件中)
-(DSManagedObject *)DScopy; NS_RETURNS_RETAINED;
NS_RETURNS...
WWDC 2011会议322的来源 - Objective-C深度进展。这个问题的关键时刻是9:10左右。
关于“但我知道Apple现在想为自己保留所有双字符前缀”的说明。作为个人偏好,我喜欢使用_
字符将前缀与名称分开,它对我来说很有用。你可能会尝试类似的东西:
-(DSManagedObject *)ds_copy; NS_RETURNS_RETAINED;
这会给你三个字符,并且可以说方法名称更具可读性。
修改以回复评论中发布的链接。
然而,正如贾斯汀对原始问题的回答所说,这可以被打破。
关于属性;我没有建议使用__attribute__((objc_method_family(copy)))
我建议使用NS_RETURNS_RETAINED
,其转换为:__attribute__((ns_returns_retained))
。虽然第一个例子甚至不会使用- (NSString *)string __attribute__((objc_method_family(copy)));
进行编译(正如他所说),但它只能编译- (NSString *)string; NS_RETURNS_RETAINED;
。
显然,如果NS_RETURNS_..
被编译器“隐藏”在单独的.m
中,或者以某种其他方式被指向,并且编译器无法看到指令,那么它将无效。因此,我建议将任何可能导致分析器/编译器混淆的方法的声明放在主.h
文件(导入所有其他文件的文件)中,以限制出现问题的可能性。< / p>