ios 在Objective-C中,方法的绑定真的发生在“运行时”吗?

omtl5h9j  于 2023-06-07  发布在  iOS
关注(0)|答案(3)|浏览(116)

我听说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一个消息sayHelloTestbrad不知道如何处理。我希望这个错误不会在编译时发生。
但是,编译器仍然会抛出错误:

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”被称为“动态类型语言”?
有人对此有什么想法吗?

j9per5c4

j9per5c41#

编译器的一个任务是在编译时捕获尽可能多的错误。如果它知道调用将在运行时失败,您通常希望它发出抱怨。
您可以通过强制转换来抑制它,以显示运行时解析正在发生:

[(id)brad sayHelloTest];
vltsax25

vltsax252#

因为IDE可以从上下文推断出明显的错误。
当你写if (a = 1)时,你会得到一个警告。一个好的IDE应该帮助你尽早发现错误。

frebpwbc

frebpwbc3#

我终于找到原因了。
编译时会抛出错误,因为包含了-Werror标志,会将warning变成error..
http://clang.llvm.org/docs/UsersManual.html#cmdoption-Werror
在我删除-Werror标志后,一切都按预期工作,错误只发生在运行时。

相关问题