神经病院objc runtime入院考试
《神经病眼中的objc runtime》北京线下分享活动顺利完成,为了配合讲解编造的几个runtime考题发出来分享下:
- 为分享内容配合讲解用,可不是为了面试别人的哦(容易被抽)
- 这几个题分别对应了runtime中几个隐蔽的知识点,挺非主流的,没必要深究
- 答案在本页末尾给出,有同学针对这几道题写了讲解,所以就一笔带过了
- 分享的具体内容争取找个时间写个blog总结下
神经病院objc runtime入院考试
(1) 下面的代码输出什么?
1 | @implementation Son : Father |
(2) 下面代码的结果?
1 | BOOL res1 = [(id)[NSObject class] isKindOfClass:[NSObject class]]; |
(3) 下面的代码会?Compile Error / Runtime Crash / NSLog…?
1 | @interface NSObject (Sark) |
(4) 下面的代码会?Compile Error / Runtime Crash / NSLog…?
1 | @interface Sark : NSObject |
答案
(1) Son / Son 因为super为编译器标示符,向super发送的消息被编译成objc_msgSendSuper
,但仍以self作为reveiver
(2) YES / NO / NO / NO <NSObject>
协议有一套类方法的隐藏实现,所以编译运行正常;由于NSObject meta class的父类为NSObject class,所以只有第一句为YES
(3) 编译运行正常,两行代码都执行-foo
。 [NSObject foo]方法查找路线为 NSObject meta class –super-> NSObject class,和第二题知识点很相似。
(4)编译运行正常,输出ViewController中的self
对象。 编译运行正常,调用了-speak
方法,由于
1 | id cls = [Sark class]; |
obj
已经满足了构成一个objc对象的全部要求(首地址指向ClassObject),遂能够正常走消息机制;
由于这个人造的对象在栈上,而取self.name
的操作本质上是self指针在内存向高位地址偏移(32位下一个指针是4字节),按viewDidLoad执行时各个变量入栈顺序从高到底为(self, _cmd, self.class, self, obj)(前两个是方法隐含入参,随后两个为super调用的两个压栈参数),遂栈低地址的obj+4取到了self。