什么时候定义Objective-C方法? [英] When do I define objective-c methods?

查看:117
本文介绍了什么时候定义Objective-C方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm learning Objective-C, and have a C/C++ background.

  • 在面向对象的C ++中,即使在父类中声明了方法,也始终需要在定义(实现)该方法之前先声明该方法.

  • In object-oriented C++, you always need to declare your method before you define (implement) it, even if it is declared in the parent class.

在过程样式C(IIRC)中,只要在以后的同一个编译单元(即,相同文件)中仅从其他地方调用函数,就可以定义一个函数.文件(好吧,前提是您未在其他地方用"extern"声明它).

In procedural-style C, IIRC, you can get away with just defining a function so long as it is only called from something else in the same compilational unit (ie. the same file) that came later on in the file (well, provided you don't declare it elsewhere with "extern").

现在,在Objective-C中,似乎只需要在头文件中声明选择器(如果它们将被外部对象使用),并且您可以仅在.m文件中构成选择器.很好,然后在.m文件中调用它们.而且,似乎从未(重新)定义委托方法或继承的方法.

Now, in Objective-C, it appears that you only need to declare selectors in the header file if they are going to be used by something external, and that you can make up selectors in your .m file just fine, and call them within the .m file. Also, it appears that delegate methods or inherited methods are never (re)defined.

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

Am I on the right track? When do you need to define a selector in Objective-C?

推荐答案

对于Objective-C方法,通常的做法是将希望公开的方法放在头文件的@interface部分中,以便其他代码只能包含.h,并知道如何与您的代码进行交互.基于订单的惰性声明"就像C中的函数一样工作—您不必必须声明方法原型,除非您具有无法通过排序解决的依赖关系,但可以添加方法@implementation内部的原型(如果需要).

For Objective-C methods, the general practice is to put methods you wish to expose in the @interface section of the header file so other code can include only the .h and know how to interact with your code. Order-based "lazy declaration" works just like functions in C — you don't have to declare a method prototype unless you have a dependency that can't be resolved by ordering, but you can add method prototypes inside the @implementation if needed.

是的,您在正确的轨道上.不要为继承的方法重复方法原型-编译器会在父级的头文件中找到它.可以将委托方法定义为类别中的原型(添加到类中)并根据需要实现,但是委托不需要提供方法原型,因为它已经定义. (如果要澄清等,它仍然可以.)

So yes, you're on the right track. Don't repeat the method prototype for inherited methods — the compiler finds it in the parent's header file. Delegate methods may be defined as prototypes in a category (tacked onto a class) and implemented as desired, but the delegate does not need to provide a method prototype, since it is already defined. (It still can if it wants to for clarity, etc.)

由于您只是在学习Objective-C,因此此答案的其余部分比您要求的要详细得多.你被警告了. ;-)

当您静态键入变量(例如,用MyClass*而不是id)时,如果您尝试调用某个方法,该方法不会通告其实现,则编译器会警告您,无论它是否实现.如果您动态键入变量,则编译器不会阻止您调用任何您喜欢的内容,并且仅当您调用不存在的内容时才会出现运行时错误.就语言而言,您可以在运行时调用类实现的任何方法而不会出错-无法限制谁可以调用方法.

When you statically type a variable (e.g. MyClass* instead of id) the compiler will warn you when you try to call a method that a class doesn't advertise that it implements, whether it does or not. If you dynamically type the variable, the compiler won't stop you from calling whatever you like, and you'll only get runtime errors if you call something that doesn't exist. As far as the language is concerned, you can call any method that a class implements without errors at runtime — there is no way to restrict who can call a method.

我个人认为这实际上是一件好事.我们习惯于封装和保护我们的代码,使其免受其他代码的侵害,以至于有时我们将调用者视为de回的不道德行为,而不是可信赖的同事或客户.我发现以您尽力而为,我尽我所能"的思维方式进行编码非常令人愉快,每个人都尊重边界并照顾好自己的事情.您可能会说,Objective-C的态度"是社区信任的一种,而不是严格的执行.例如,我很乐意为来到我办公桌前的任何人提供帮助,但是如果有人不经意就弄乱我的东西或四处走动,我会很生气.精心设计的代码不必太偏执或反社会,只需协同工作即可. :-)

Personally, I think this is actually a good thing. We get so used to encapsulation and protecting our code from other code that we sometimes treat the caller as a devious miscreant rather than a trustworthy coworker or customer. I find it's quite pleasant to code with a mindset of "you do your job and I do mine" where everyone respects boundaries and takes care of their own thing. You might say that the "attitude" of Objective-C is one of community trust, rather than of strict enforcement. For example, I'm happy to help anyone who comes to my desk, but would get really annoyed if someone messed with my stuff or moved things around without asking. Well-designed code doesn't have to be paranoid or sociopathic, it just has to work well together. :-)

也就是说,有很多方法来构造接口,具体取决于您希望/需要向用户公开接口的粒度级别.您在公共标头中声明的任何方法本质上都是公平的游戏,任何人都可以使用.隐藏方法声明有点像锁住您的汽车或房屋-可能不会让所有人都离开,但是(1)通过不诱使他们不要让他们弄乱的东西来使诚实的人诚实",以及(2 )参加的任何人肯定会知道自己不应该这样做,也不能真正抱怨负面后果.

That said, there are many approaches for structuring your interfaces, depending on the level of granularity you want/need in exposing interfaces to users. Any methods you declare in the public header are essentially fair game for anyone to use. Hiding method declarations is a bit like locking your car or house — it probably won't keep everyone out, but (1) it "keeps honest people honest" by not tempting them with something they shouldn't be messing with, and (2) anyone who does get in will certainly know they weren't supposed to, and can't really complain of negative consequences.

以下是我用于文件命名的一些约定,以及每个文件中包含的内容-从底部的.m文件开始,每个文件都包括上方的文件. (使用严格的include链将防止出现重复的符号警告之类的问题.)其中一些级别仅适用于较大的可重用组件,例如Cocoa框架.根据您的需要对其进行调整,并使用任何适合您的名称.

Below are some conventions I use for file naming, and what goes in each file — starting from a .m file at the bottom, each file includes the one above it. (Using a strict chain of includes will prevent things like duplicate symbol warnings.) Some of these levels only apply to larger reusable components, such as Cocoa frameworks. Adapt them according to your needs, and use whatever names suit you.

  • MyClass.h —公共API(应用程序编程接口)
  • MyClass_Private.h —公司内部的SPI(系统编程接口)
  • MyClass_Internal.h —项目内部IPI(内部编程接口)
  • MyClass.m-通常实现所有API/SPI/IPI声明
  • MyClass_Foo.m —其他实现,例如类别
  • MyClass.h — Public API (Application Programming Interface)
  • MyClass_Private.h — Company-internal SPI (System Programming Interface)
  • MyClass_Internal.h — Project-internal IPI (Internal Programming Interface)
  • MyClass.m — Implementation, generally of all API/SPI/IPI declarations
  • MyClass_Foo.m — Additional implementation, such as for categories

API供所有人使用,并且受到公共支持(通常在Foo.framework/Headers中). SPI为代码的内部客户端提供了其他功能,但应了解支持可能会受到限制并且接口可能会更改(通常在Foo.framework/PrivateHeaders中). IPI包含特定于实现的详细信息,这些详细信息切勿在项目本身之外使用,并且这些标头根本不包含在框架中.选择使用SPI和IPI调用的任何人均需自担风险,并且通常在更改破坏其代码时会受到损害. :-)

API is for everyone to use, and is publicly supported (usually in Foo.framework/Headers). SPI exposes additional functionality for internal clients of your code, but with the understanding that support may be limited and the interface is subject to change (usually in Foo.framework/PrivateHeaders). IPI consists of implementation-specific details that should never be used outside the project itself, and these headers are not included in the framework at all. Anyone who chooses to use SPI and IPI calls does so at their own risk, and usually to their detriment when changes break their code. :-)

这篇关于什么时候定义Objective-C方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆