开启汇编的步骤:Debug->Debug Workflow->Always Show Disassembly
objc_msgSend
打断点然后同时点击control和箭头所指进入
https://opensource.apple.com
SEL->IMP
CacheLookup:1、有缓存机制
2、CacheHit找到缓存
3、CheckMiss->MethodTableLookup
4、add
对象->结构体->class
class:1、方法列表
2、属性列表
3、协议列表
---------------------------------------以上快速查找---------------------------------
IMP_class_lookupMethodAndLoadCache3(id obj,SEL sel,Class cls){
return lookUpImpOrForward(cls, sel,obj,YES/*initialize*/,NO/*cache*/,YES/*resolver*/);
}
慢速查找:cls类对象、实例对象、元类对象
⚠️实例方法存在类对象里面
⚠️类方法存在元类里面
⚠️方法查找首先在自己的类的方法列表里查找,有的话直接log_and_fill_cache,没有的话去父类中查找,如果父类中有,也要log_and_fill_cache,一直找到NSObject
unsigned attempts = unreasonableClassCount();
for (Class curClass = cls ->superclass;
curClass != nil;
curClass = curClass ->superclass)
{
if(--attempts == 0){
_objc_fatal("Memory corruption in class list.")
}
imp = cache_getImp(curClass, sel);
if(imp){
if(imp != (IMP)_objc_msgForward_impcache){
log_and_fill_cache(cls,imp,sel,inst,curclass);
goto done;
}
else{
break;
}
}
Method meth = getMethodNoSuper_nolock(curClass,sel);
if(meth){
log_and_fill_cache(cls,meth->imp,sel,inst, curClass);
imp = meth->imp;
goto done;
}
if(resolver && !triedResolver){
runtimeLock.unlock();
_class_resolveMethod(cls,sel,inst);
runtimeLock.lock();
triedResolver = YES;
goto retry;
}
}
isa走位图
动态方法解析
⚠️消息转发流程如下图所示:
⚠️⚠️⚠️动态方法解析只解析一次
//类方法动态解析
void _class_resolveMethod(Class cls,SEL sel,id inst)
{
if(! cls -> isMetaClass()){
_class_resolveInstanceMethod(cls,sel,inst);
}
else{
_class_resolveClassMethod(cls,sel,inst);
if(!lookUpImpOrNil(cls,sel,inst
NO/*initialize*/,YES/*cache*/,NO/*resolver*/))
}
}
//实例方法动态解析
static void _class_resolveInstanceMethod(Class cls,SEL sel,id inst)
{
if(! lookUpImpOrNil(cls->ISA(),SEL_resolveInstanceMethod,cls,
NO/*initialize*/,YES/*cache*/,NO/*resolver*/)){
return;
}
BOOL (*msg)(Class,SEL,SEL) = (typeof(msg))objc_msgSend;
bool resolved = msg(cls,SEL_resolveInstanceMethod, sel);
IMP imp = lookUpImpOrNil(cls,sel,inst,NO/*initialize*/,YES/*cache*/,NO/*resolver*/);
if(resolver && PrintResolving){
if(imp){
_objc_inform(@"RESOLVE:method %c[%s %s] " "dynamically resolved to %p", cls - > isMetaClass()?'+':'-',cls->nameForLogginh(),sel_getName(sel),imp);
}
}
}
//消息转发
-(id)forwardingTargetForSelector:(SEL)aSelector{
NSLog(@"%s",__func__);
return [super forwardingTargetForSelector: aSelector];
}
-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
//方法签名
if(aSelector == @selector(run)){
Method method = class_getInstanceMethod([self class],@selector(runMethod));
const char *type = method_getTypeEncoding(method);
return [NSMethodSignature methodSignatureForSelector: aSelector];
}
return [NSMethodSignature methodSignatureForSelector: aSelector];
}
-(void)forwardInvocation:(NSInvocation *)anInvocation{
NSLog(@"%s-%@",__func__,NSStringFromSelector(anInvocation.selector));
anInvocation.selector = @selector(runMethod);
[anInvocation invoke];
}
网友评论