我正在学习 Objective-C,并且有 C/C++ 背景。

  • 在面向对象的 C++ 中,您始终需要在定义(实现)方法之前声明它,即使它是在父类中声明的。

  • 在过程式 C、IIRC 中,只要定义一个函数,只要它仅从同一编译单元中的其他内容调用即可(即相同的文件)稍后出现在文件中(好吧,前提是您不使用“extern”在其他地方声明它)。

  • 现在,在 Objective-C 中,似乎您只需要在头文件中声明选择器(如果它们要被外部使用),并且您可以在 .m 文件中很好地组成选择器,并在内部调用它们.m 文件。此外,委托方法或继承方法似乎永远不会(重新)定义。

我走在正确的轨道上吗?什么时候需要在 Objective-C 中定义选择器?

有帮助吗?

解决方案

对于 Objective-C 方法,一般做法是将您想要公开的方法放在 @interface 头文件的部分,以便其他代码可以仅包含 .h 并知道如何与您的代码交互。基于顺序的“惰性声明”就像 C 中的函数一样工作——你不需要 必须 声明方法原型,除非您有无法通过排序解决的依赖关系,但您可以在 @implementation 如果需要的话。

所以是的,你走在正确的道路上。不要重复继承方法的方法原型 - 编译器会在父级的头文件中找到它。委托方法可以定义为类别中的原型(附加到类上)并根据需要实现,但委托不需要提供方法原型,因为它已经定义了。(如果为了清楚起见,它仍然可以)

由于您刚刚学习 Objective-C,所以这个答案的其余部分比您要求的要详细得多。你被警告了。;-)


当您静态键入变量时(例如 MyClass* 代替 id)当您尝试调用某个类未声明其实现的方法(无论是否实现)时,编译器都会向您发出警告。如果您动态输入变量,编译器不会阻止您调用您喜欢的任何内容,并且只有在调用不存在的内容时才会出现运行时错误。就语言而言,您可以在运行时调用类实现的任何方法而不会出现错误 - 无法限制谁可以调用方法。

就我个人而言,我认为这实际上是一件好事。我们已经习惯了封装和保护我们的代码免受其他代码的影响,以至于有时我们将调用者视为狡猾的恶棍,而不是值得信赖的同事或客户。我发现以“你做你的工作,我做我的”的心态来编码是非常愉快的,每个人都尊重界限并照顾自己的事情。你可能会说Objective-C的“态度”是一种社区信任,而不是严格执行。例如,我很乐意帮助任何来到我办公桌前的人,但如果有人弄乱我的东西或在没有询问的情况下移动东西,我会非常生气。设计良好的代码不一定是偏执或反社会的,它只需能够很好地协同工作即可。:-)

也就是说,构建界面的方法有很多,具体取决于您向用户公开界面时想要/需要的粒度级别。您在公共标头中声明的任何方法对于任何人来说本质上都是公平的。隐藏方法声明有点像锁上你的车或房子——它可能不会把每个人都拒之门外,但是(1)它不会用他们不应该乱搞的东西来诱惑他们,从而“让诚实的人保持诚实”,并且(2 ) 无论谁 进入的人肯定知道他们不应该这样做,并且不能真正抱怨负面后果。

以下是我用于文件命名的一些约定,以及每个文件中的内容 - 从底部的 .m 文件开始,每个文件都包含其上面的文件。(使用严格的包含链可以防止重复符号警告等情况。)其中一些级别仅适用于较大的可重用组件,例如 Cocoa 框架。根据您的需要调整它们,并使用任何适合您的名称。

  • MyClass.h — 公共API(应用程序编程接口)
  • MyClass_Private.h — 公司内部 SPI(系统编程接口)
  • MyClass_Internal.h — 项目内部IPI(内部编程接口)
  • MyClass.m — 通常所有 API/SPI/IPI 声明的实现
  • MyClass_Foo.m - 额外的实现,例如类别

API供所有人使用,并且是公开支持的(通常在 Foo.framework/Headers)。SPI 为代码的内部客户端公开了附加功能,但要理解支持可能有限并且接口可能会发生变化(通常在 Foo.framework/PrivateHeaders)。IPI 由特定于实现的细节组成,这些细节永远不应在项目本身之外使用,并且这些标头根本不包含在框架中。任何选择使用 SPI 和 IPI 调用的人都需要自行承担风险,并且当更改破坏其代码时通常会造成损害。:-)

其他提示

在头文件中声明方法只会停止编译器警告。Objective-C 是一种动态语言,因此您可以向对象调用方法(发送消息),无论该方法是否在外部声明。

此外,如果您在 .m 文件中在调用该方法的任何代码上方定义一个方法(惰性声明),则不会生成任何警告。然而,同样的事情也适用,您可以在不声明对象的情况下向对象发送消息。

当然 - 这意味着 Objective-C 中没有私有方法。类实现的任何方法都可以被调用。

个人喜好。如果它是一种公共方法(即外部使用的方法)。在 .h 中声明并在 .m 中定义。如果您想限制它的可见性,或者至少表明它是私有方法,请使用 类别/类扩展 在 .m 文件中。尽管很多示例代码都使用了惰性声明方法。

Objective-C 将函数视为“消息”,因此,您可以向任何对象发送“消息”——即使是没有在其接口中明确声明它可以接受的对象。因此,Obj-C 中不存在私有成员之类的东西。

这可能非常强大,但对于新的 Obj-C 程序员来说却是一个困惑的根源——尤其是那些来自 C++、Java 或 C# 的程序员。以下是基本经验法则:

  • 您应该在 @interface 中定义所有公共方法,以便消费者知道您期望处理哪些消息。
  • 您应该在 @interface 中定义 @private 方法,以避免编译器消息,并避免必须在 @implementation 中对方法进行排序。
  • 在为您的类实现特定的方法约定时,您应该使用协议。

其中大部分是个人喜好,但它有助于避免烦人的编译器警告并保持代码井井有条。并且易于理解。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top