一道iOS面试题,关乎OC是如何寻找类方法实现的细节

题目描述

下面的代码运行的结果是什么? 崩溃 还是 打印?

@interface NSObject(Test)

+ (void)foo;

- (void)foo;

@end

@implementation NSObject(Test)

//+ (void)foo {

// NSLog(@"+ foo");

//}

- (void)foo {

NSLog(@"- foo");

}

@end

int main(int argc, const char * argv[]) {

@autoreleasepool {

// insert code here...

[NSObject foo];

[[NSObject new] foo];

}

return 0;

}

测试结果

测试结果是可以运行的,结果如下:

2020-07-22 11:14:10.938981+0800 Test[3689:80562] - foo

2020-07-22 11:14:10.939060+0800 Test[3689:80562] - foo

我又实现了 + foo 方法,进行了测试,结果如下:

2020-07-22 11:15:40.686320+0800 Test[3712:81812] + foo

2020-07-22 11:15:40.686375+0800 Test[3712:81812] - foo

疑问

  1. 在没有实现 + foo方法时,为什么 + foo方法的IMP 会变成 - foo方法的IMP?
  2. 实现了 + foo方法后,为什么 + foo 方法的IMP 却没有变成 - foo方法的IMP?编译器到底是怎么关联类方法的SEL和IMP?

结语

希望研究过这块的朋友能告诉我这些细节的资料在哪里? 提前感谢 。

回答:

isa 与 superClass

如图,所有元类的isa指针都指向 NSObject 的元类,NSObjct元类 的 superClass 指向NSObject 自身。
题目中,category 分别将 +foo 和 -foo 添加到 NSObject元类 和 NSObject 类对象中,形成类方法与实例方法。
[[NSObject new] foo] 在 NSObject 类对象中找到 -foo 并执行;
[NSObject foo] 在 NSObject元类中找 +foo 方法,没有找到,再去 superClass 中找,也就是去 NSObject 类对象中找 +foo 方法;而我们知道,OC中的方法都是通过字符串匹配的,所以最终匹配到的是同名的 -foo 方法,然后执行。

以上是 一道iOS面试题,关乎OC是如何寻找类方法实现的细节 的全部内容, 来源链接: utcz.com/p/184287.html

回到顶部