我正在学习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文件中使用类别/类扩展.虽然许多示例代码使用惰性声明方法.