关于声明:我什么时候定义objective-c方法?

When do I define objective-c methods?

我在学习Objto-C,有C/C++背景。

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

  • 在过程风格c,iirc中,只要函数只从文件后面的同一编译单元(即同一文件)中的其他对象调用(好吧,前提是不在其他地方用"extern"声明它),就可以不定义函数。

  • 现在,在objective-c中,如果选择器将被外部对象使用,那么您只需要在头文件中声明它们,并且您可以在.m文件中很好地构造选择器,并在.m文件中调用它们。此外,似乎从未(重新)定义委托方法或继承方法。

我走对了吗?您何时需要在Objective-C中定义选择器?


对于Objective-C方法,一般的做法是将您希望公开的方法放在头文件的@interface部分,这样其他代码只能包含.h并知道如何与代码交互。基于顺序的"懒惰声明"与C中的函数一样工作——除非您有一个不能通过排序解决的依赖项,否则不必声明方法原型,但如果需要,您可以在@implementation中添加方法原型。好的。

是的,你走对了。不要为继承的方法重复方法原型-编译器会在父级的头文件中找到它。委托方法可以定义为类别中的原型(附加到类上)并根据需要实现,但是委托不需要提供方法原型,因为它已经被定义了。(为了清晰起见,它还是可以的,等等)好的。

因为你只是在学习目标C,所以剩下的答案比你要求的要详细得多。有人警告过你。;-)好的。

当您静态地键入一个变量(例如,MyClass*而不是id时,编译器会在您试图调用一个方法时发出警告,说明某个类没有公布它实现了什么,不管它是否实现。如果动态地键入变量,编译器不会阻止您调用所需的任何内容,并且只有调用不存在的内容时才会出现运行时错误。就语言而言,可以在运行时调用类实现的任何方法,而不会出现错误——无法限制谁可以调用方法。好的。

就个人而言,我认为这实际上是一件好事。我们习惯于封装和保护代码不受其他代码的影响,因此有时我们会将调用者视为一个狡猾的错误者,而不是值得信赖的同事或客户。我觉得用"你做你的工作,我做我的工作"的心态来编码是非常愉快的,因为每个人都尊重自己的界限,关心自己的事情。你可以说,客观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文件中的任何调用它的代码(lazy声明)上方定义了一个方法,那么它将不会生成任何警告。但是,同样的事情也适用,您可以将消息发送到一个对象,而不必声明它。

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

个人偏好。如果是公共方法(即外部使用的方法)。在.h中声明它并在.m中定义。如果要限制它的可见性,或者至少指示它是私有方法,请在.m文件中使用类别/类扩展名。尽管许多示例代码使用了Lazy声明方法。


Objective-C将函数视为"消息",因此,您可以向任何对象发送"消息",甚至是在它的接口中没有显式声明它可以接受的对象。因此,在obj-c中没有私有成员这样的东西。

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

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

这其中大部分是个人偏好,但是它有助于避免恼人的编译器警告并保持代码的有序性。很容易理解。