序言
现在面试的时候,runtime被面试到的概率为百分之百,所以为了获得一个更好的工作,薪资更高的工作,非常有必要对runtime有一个全面而深入的理解,本文可以帮助读者实现这个愿望,详情请看下文。
一 面试题
1.讲一下 OC 的消息机制
- OC中的方法调用其实都是转成了objc_msgSend函数的调用,给receiver(方法调用者)发送了一条消息(selector方法名)
- objc_msgSend底层有3大阶段
- 消息发送(当前类、父类中查找)、动态方法解析、消息转发
2. 什么是Runtime?平时项目中有用过么?
- OC是一门动态性比较强的编程语言,允许很多操作推迟到程序运行时再进行
- OC的动态性就是由Runtime来支撑和实现的,Runtime是一套C语言的API,封装了很多动态性相关的函数
- 平时编写的OC代码,底层都是转换成了Runtime API进行调用
3.runtime具体应用
- 利用关联对象(AssociatedObject)给分类添加属性
- 遍历类的所有成员变量(修改textfield的占位文字颜色、字典转模型、自动归档解档)
- 交换方法实现(交换系统的方法)
- 利用消息转发机制解决方法找不到的异常问题
4.如下代码执行结果
#import <Foundation/Foundation.h>
#import "CSPersion.h"
@interface CSStudent : CSPersion
@end
#import "CSStudent.h"
@implementation CSStudent
- (instancetype)init
{
self = [super init];
if (self) {
NSLog(@"[self class] = %@",[self class]);
NSLog(@"[super class] = %@",[super class]);
NSLog(@"[self superclass] = %@",[self superclass]);
NSLog(@"[super superclass] = %@",[super superclass]);
}
return self;
}
@end
#import <Foundation/Foundation.h>
#import "CSStudent.h"
#import "CSPersion.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
CSStudent *student = [[CSStudent alloc] init];
}
return 0;
}
执行结果
5.依旧是上述类,执行完如下代码执行结果
#import <Foundation/Foundation.h>
#import "CSStudent.h"
#import "CSPersion.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
BOOL rs1 = [[NSObject class] isKindOfClass:[NSObject class]];
BOOL rs2 = [[NSObject class] isMemberOfClass:[NSObject class]];
BOOL rs3 = [[CSPersion class] isKindOfClass:[CSPersion class]];
BOOL rs4 = [[CSPersion class] isMemberOfClass:[CSPersion class]];
NSLog(@"rs1 = %d,rs2 = %d,rs3 = %d,rs4 = %d",rs1,rs2,rs3,rs4);
}
return 0;
}
执行结果
6.执行完如下代码,打印结果
#import <Foundation/Foundation.h>
@interface CSPersion : NSObject
/** name*/
@property(nonatomic,strong)NSString *name;
- (void)print;
@end
#import "CSPersion.h"
@implementation CSPersion
- (void)print {
NSLog(@"my name is %@",self.name);
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
id cls = [CSPersion class];
void *obj = &cls;
[(__bridge id)obj print];
}
return 0;
}
运行结果
7.说说什么是runtime
1.OC 是一个全动态语言,OC 的一切都是基于 Runtime 实现的平时编写的OC代码, 在程序运行过程中, 其实最终都是转成了runtime的C语言代码, runtime算是OC的幕后工作者
比如:
OC :
[[Person alloc] init]
runtime :
objc_msgSend(objc_msgSend("Person" , "alloc"), "init")
2.runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API
3.runtimeAPI的实现是用 C++ 开发的(源码中的实现文件都是mm),是一套苹果开源的框架
更多有关runtime文章请看下面
iOS-runtime-API详解+使用
iOS - runtime -详解
iOS Runtime原理及使用
iOS - runtime如何通过selector找到对应的 IMP地址(分别考虑类方法和实例方法)
iOS - Runtime之面试题详解一
iOS runtime的使用场景-实战篇