1

我刚刚开始阅读我的第一本 Objective-C 书,而且大部分内容都很清楚,但是我想了解为什么它教我首先在接口中声明一个方法,我尝试从接口中删除它并在实现中执行它部分和所有似乎都有效,所以我的问题是它是否重要,如果是,这有助于完成什么?

4

3 回答 3

2

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

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

于 2012-11-06T00:22:45.127 回答
1

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

于 2012-11-06T00:23:03.540 回答
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 编程语言:定义类 - 接口的角色)。

于 2012-11-06T00:26:52.357 回答