目标C,为什么在界面中声明方法

时间:2012-11-06 00:21:03

标签: objective-c

我刚刚开始阅读我的第一本Objective-C书并且它非常清楚,但是我想理解为什么它教会我先在界面中声明一个方法,我试过从界面中删除它并只是这样做在实现部分,所有似乎都工作,所以我的问题是否重要,如果是这样,这有助于实现什么?

3 个答案:

答案 0 :(得分:2)

它是C.在标头中声明函数/方法允许其他编译单元查看函数原型并基于它们进行编译。 Objective-C虽然通过动态调度工作,但即使你没有在头文件中声明一个方法,它仍然存在于运行时。当你调用一个方法时,它会在运行时被解析,所以它是否在标题中并不重要。

唯一的问题是,如果您不在头文件中包含该方法,则编译器必须对返回和参数类型进行假设。默认为id,取决于您的体系结构,这是4或8个字节,因此如果实际返回类型具有不同的大小(例如结构或BOOL等),您将遇到麻烦。 / p>

答案 1 :(得分:1)

您必须在接口(标头)中声明您的方法以使其公开(可由其他类访问)。如果您只在类中内部使用方法,则不必在界面中声明它。

答案 2 :(得分:1)

Objective-C是一种高度动态的语言(和运行时),可以尽可能地推迟决策。

代码运行正常,因为在运行时对象确实会响应您指定的选择器。

通过声明方法,您可以帮助Objective-C编译器帮助您检查在运行时不会遇到任何意外情况。

例如,参加以下课程:

@interface MDFoo : NSObject
- (void)blah;
@end


@implementation MDFoo

- (void)blah {
    NSLog(@"[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
}

- (void)boo {
    NSLog(@"[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
}

@end

假设在另一个控制器类中,您创建了MDFoo的实例,并希望向其发送一些消息。

MDFoo *foo = [[MDFoo alloc] init];
[foo blah];
[foo boo]; // compiler warning
[foo yell]; // compiler warning

编译程序时,编译器应该警告您无法找到最后两个方法,并且MDFoo的实例可能无法响应这些选择器。

如果您随后运行该程序,则会记录以下内容:

foo[10540:303] [MDFoo blah]
foo[10540:303] [MDFoo boo]
foo[10540:303] -[MDFoo yell]: unrecognized selector sent to instance 0x1001082f0
foo[10540:303] *** Terminating app due to uncaught exception
            'NSInvalidArgumentException', reason: '-[MDFoo yell]:
                 unrecognized selector sent to instance 0x1001082f0'

因此,在运行时,关于boo的警告结果不算什么,但有关yell的警告是正确的,导致应用程序终止。

从设计的角度来看,它也是让你让其他对象知道可以调用哪些消息的方式。 (见Objective-C Programming Language: Defining a Class - The Role of the Interface)。