我听说Objective-C受到SmallTalk的“消息传递机制”的影响。
Objective-C和Smalltalk一样,可以使用动态类型:可以向对象发送未在其接口中指定的消息。这可以允许增加的灵活性,因为它允许对象“捕获”消息并将消息发送到可以适当地响应消息的不同对象,或者同样地将消息发送到另一个对象。
我觉得像[anObject someMethod]
这样的代码,someMethod
到机器码的绑定可能发生在运行时。
因此,我写了一个这样的demo:
#import <Foundation/Foundation.h>
@interface Person : NSObject {
@private char *name;
}
@property (readwrite, assign) char *name;
- (void)sayHello;
@end
@implementation Person
@synthesize name;
- (void)sayHello {
printf("Hello, my name is %s!\n", [self name]);
}
@end
int main() {
Person *brad = [Person new];
brad.name = "Brad Cox";
[brad sayHello];
[brad sayHelloTest];
}
我尝试[brad sayHelloTest]
发送brad
一个消息sayHelloTest
,brad
不知道如何处理。我希望这个错误不会在编译时发生。
但是,编译器仍然会抛出错误:
main.m:24:11: error: instance method '-sayHelloTest' not found (return type defaults to 'id') [-Werror,-Wobjc-method-access]
[brad sayHelloTest];
^~~~~~~~~~~~
main.m:3:12: note: receiver is instance of class declared here
@interface Person : NSObject {
^
将[(id)brad sayHelloTest]
更改为[(id)brad sayHelloTest];
也不起作用。(编译命令为clang -Wall -Werror -g -v main.m -lobjc -framework Foundation -o main
)
在Objective-C中,方法的绑定真的发生在“运行时”吗?如果是这样,为什么会出现这样的编译器错误?
如果绑定不是发生在“运行时”,为什么“Objective-C”被称为“动态类型语言”?
有人对此有什么想法吗?
3条答案
按热度按时间j9per5c41#
编译器的一个任务是在编译时捕获尽可能多的错误。如果它知道调用将在运行时失败,您通常希望它发出抱怨。
您可以通过强制转换来抑制它,以显示运行时解析正在发生:
vltsax252#
因为IDE可以从上下文推断出明显的错误。
当你写
if (a = 1)
时,你会得到一个警告。一个好的IDE应该帮助你尽早发现错误。frebpwbc3#
我终于找到原因了。
编译时会抛出错误,因为包含了
-Werror
标志,会将warning变成error..http://clang.llvm.org/docs/UsersManual.html#cmdoption-Werror
在我删除
-Werror
标志后,一切都按预期工作,错误只发生在运行时。