oc中调用方法其实就是向对象发送消息,在编译Objective-C函数调用的语法时,会被翻译成一个C的函数调用:objc_msgSend(),例如:
那么,objc_msgSend又做了哪些事呢?,以[object foo]为例:
1.通过object的isa指针找到它的class
2.在class的method_list中找到foo
3.如果class中没找到foo,则继续往他的superclass中查找
4.一旦找到foo这个函数,就去执行对应的方法实现(IMP)
NSMethodSignature(方法签名)
方法签名:用语记录一个方法的参数和返回值类型的类。类似于objc_method_description结构体。方法签名是用于初始化NSInvocation用的。
用于记录一个消息(方法)的接收者(target)方法名(SEL)参数类型,参数等信息,包含执行该消息方法的类。
此类类似于结构体Method。
他提供了- (void)invokeWithTarget:(id)target;调用对象中的方法。类似于id method_invoke(id receiver, Method m, …) 函数。
注意:NSMethodSignature,NSInvocation一般我们都是用语消息转发时候用到。正常我们用的比较少。
二、动态方法决议与消息转发
消息转发机制基本上分为三个步骤:
1. 动态方法解析:- (BOOL)resolveInstanceMethod:(SEL)sel;+ (BOOL)resolveClassMethod:(SEL)sel 返回添加新方法并YES
2. 备用接收者
-(id)forwardingTargetForSelector:(SEL)aSelector
如果一个对象实现了这个方法,并返回一个非nil的对象,则返回的对象会作为消息的新接收者,且消息会被分发到这个对象。当然这个对象不能是self自身,否则就是出现无限循环。当然,如果我们没有指定相应的对象来处理aSelector,则应该调用父类的实现来返回结果。
3. 完整转发
如果在上一步还不能处理未知消息,则唯一能做的就是启用完整的消息转发机制了。
此时会调用以下方法:
-(void)forwardInvocation:(NSInvocation*)anInvocation
由于NSInvocation的初始化需要有一个方法签名NSMethodSignature,所以我们还需要实现下面的方法,该方法的返回值用于初始化NSInvocation的。
-(NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector
methodSignatureForSelector用来生成方法签名,这个签名就是给forwardInvocation中的参数NSInvocation调用的。
网友评论