Objective-C私有和公共方法的区别以及是否在头文件中声明?

9
什么是Objective-C中私有方法的最佳实践方法?也就是说,这是一个仅作为类帮助方法使用的方法。
特别是,我不清楚的是:
1. 是否需要在头文件中将该方法指定为私有方法?即,为什么不将其从头文件中删除? 2. 如果可以将其从头文件中删除,那么拥有私有方法的意义是什么? 3. 或者,在Objective-C中根本不存在真正的私有方法,如果是这种情况,那么最好只在头文件中指定所有内容,而不要标记为私有。
谢谢

1
只要实现了一个方法,就可以通过其他类来调用,因此私有方法是不存在的。将其放在 Category 中可以隐藏该方法的存在,但如果您的类实现了该方法,则可以响应它。 - Wayne Hartman
哦...好的...大多数人还是会尝试将它们标记为私有的吗,还是只是将它们公开并在*.h文件中列出真正的公共方法? - Greg
如果您想为用户提供清晰的界面,那么您不应该在头文件中列出您不希望他们使用的方法。然而,如果您不在类别扩展中声明它们(请参见我的答案),则会丧失编译器语法检查的所有优点。 Anomie的答案没有问题,但这是“C”的做法。类别扩展是实现此目的的新“Objective C”方式。 - DougW
3个回答

7
不需要在公共头文件中指定方法。如果您的模块中的类应该是“友好”的,则可以为其他类使用一个“私有”头文件。您甚至可以有一个“受保护”的头文件,就像苹果公司在UIGestureRecognizerSubclass.h中所做的那样。这只是一种约定,没有语言本身支持。
Objective-C中的私有方法只是未公开记录的方法;只要调用者知道名称以创建适当的选择器,任何方法仍然可以从任何地方调用。不公开记录方法的优点是您可以自由更改或删除它,而不必担心向后兼容性。将它们留在头文件之外是不公开记录它们的一种方式。

1
没有对你的答案提出异议--从技术上讲是正确的。然而,简单地省略声明是旧的C语言做事方式。在Objective-C 2.0中,使用类扩展在实现文件中声明方法确实是管理此问题的最佳实践。只是想确保阅读这篇文章的人们能够注意到这一点。干杯! - DougW

6
您可能想要使用的是“类扩展”。它们看起来很相似,但不应与类别混淆。这将允许您在.m文件中声明私有方法,并获得所有漂亮的IDE更正和建议。
这里有一篇不错的文章:Class Extensions Explained
还有一个相关的SO问题:Category Usage in Objective-C

这些似乎没有涵盖在“实现”/*.m文件中实现方法并在其中使用的选项 - 这样做有什么问题吗? - Greg
@Greg:这并没有比在C语言中定义函数而没有事先在某处声明它更糟糕。源文件中的顺序等也有同样的注意事项。 - Anomie
@Greg 这也可以,只要意识到你有顺序问题。例如,如果实现在源代码中使用之后,仍会收到警告。几乎每个内部都使用扩展 - 这样可以轻松地一站式查看实现清单。 - bbum
1
@Anomie - 嘿,你是不是指的是“WRT”?我不确定“WTF”怎么适用于那个句子... - DougW
哈哈,是啊。我想编辑评论,但出于某种原因它不让我编辑。 - Anomie

2

最佳实践(甚至是编译器选项检查)是所有方法都应该以某种方式声明。为了将帮助方法隐藏起来,可以在实现.m文件中声明它,例如:

#import Client;

@interface myClass (Private)
- (void) privateMethod;
- (float) bankAccountBalanceForClient:(Client *)client;
@end

@implementation myClass
- (void) privateMethod;
{
    //foo here
}

等等,私有方法是一个名为Private的myClass方法类别。该类别可以在任何地方声明,甚至在称为私有方法的主头文件中,尽管这将是维护的噩梦。

因此,使用公共.h文件来声明公共方法,使用.m文件来声明私有方法,您可以在某个地方声明所有方法。我使用此编译器选项来确保并强制执行它,以便使用的任何方法实际上都已声明(否则我会收到语法错误),因此我不会因找不到方法而导致运行时崩溃。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接