我仍然是Objective-C的新手,但我想更多地了解它应该如何完成。
我正在制作一张简单的备忘单,我想打印并放在办公室的墙上作为提示。
这是我到目前为止所拥有的:
// Headers (.h)
// Shows what's available to other classes
@interface ExampleViewController : UIViewController
// Declare public methods, ivars &
// properties that are synthesized.
@end
// Implementation (.m)
// Defines the content of the class
@interface ExampleViewController ()
// Class extension allowing to declare
// private methods, ivars & properties that are synthesized.
@end
@implementation ExampleViewController
// Private Properties
// Method definitions
@end
我不明白的一件事是为什么在实现.m文件中都有@interface和@implementation?
我知道我们可以声明私有内容,但为什么不简单地将它们放在@implementation中,如:
@implementation ExampleViewController
UIView *view; // private property
- (void)...more code
@end
#1 - 为什么我要在我的实现.m文件中使用@interface?
#2 - 对于标题.h,我为什么要使用@class
而不是#import?
#import
实际上获得了整个定义,@class
告诉编译器该符号是一个类。所以我不明白为什么我应该使用@class
?
#3 - 否则,我应该在我的.h或.m备忘单中添加任何内容吗?
这不是一个与问题相关的问题,而是一个更具维基意识的问题,所以我们每个人都可以查阅并完全快速地理解这些概念,因为对于任何新手来说都很难理解。< / p>
答案 0 :(得分:2)
为什么我应该在我的实现.m文件中使用@interface?
因为最好明确区分班级的公共和私人部分。
对于标题.h,我为什么要使用@class而不是#import?
在前向声明用于协议的类时。像这样:
@class Foo;
@protocol FooDelegate
// this wouldn't compile without a forward declaration of `Foo'
- (void)fooDidFinishAction:(Foo *)f;
@end
否则,我应该在我的.h或.m备忘单中添加任何内容吗?
这太普遍了,无法在一篇文章中回答。
答案 1 :(得分:2)
1 - 我为什么要在我的实现.m文件中使用@interface?
如果您不打算将该接口公开给任何其他组件。这肯定是私有类扩展的情况,但也可能适用于完全不需要.h
文件的测试,因为虽然它确实定义了一个类,但它不需要为任何其他组件公开接口使用。
2 - 对于标题.h,我为什么要使用@class而不是#import?
反转你的问题;为什么我应该使用#import
而不是@class
?
@class
通知编译器该名称的类定义将存在要链接,但没有说明它的接口。
#import
使您可以使用该类的界面。
前向声明需要较少的工作,并且可以允许更快的构建。也不总是#import
一个类一直都是这样的(如在@ H2CO3的协议示例中的循环引用中)。如果你需要知道的是一个类存在,那么只需使用前向声明。当您确实需要与其特定界面进行交互时(通常在您的班级实施中),您需要#import
。
3 - 否则,我应该在我的.h或.m备忘单中添加任何内容吗?
除非您打算将ivars实际暴露为公共界面(几乎肯定不是这种情况),否则请将它们从.h
中删除并仅显示属性。
让您的公共界面尽可能简单。尽量不要泄露实施细节。但是请保持足够的信息,以便类的用户可以使用该公共接口验证其行为。 (我发现只使用它的公共界面来测试类的设计是一个很好的工具,可以达到平衡。)
导入和转发声明会公开依赖项。将它们保持在您实际需要的最小值,以便您可以理解所讨论的课程实际上取决于什么。
委托协议和块类型是类接口的常见部分,但不是@interface
的一部分。如果其他类需要它们(例如注册回调),请将它们包含在.h
中。