oc調用方法流程
1.先去自己cache中查找,再去類的方法列表中查找
2.再去父類的cache中和方法列表中
//動態方法解析
3.runtime會調用resolveInstanceMethod方法和resolveCalssMethod方法給我們一次添加方法的實現的機會,在這里這調用class_addMethod方法添加方法的實現
class_addMethod([self class], sel, (IMP)aTestMethod, "v@:");
第一個參數是往哪個類里面添加方法,第二個是調用的方法選擇器,第三個是方法的實現,即函數指針,指向要添加的方法的實現,第四個是返回值和參數類型Type Encoding
如果添加成功就返回YES否則返回NO
//重定向
4.在消息轉發機制執行前runtime會允許我們替換方法的接受者即Target
通過forwrdingTargetForSelector:(SEL)aSelector方法
如果方法返回的是nil或者self則進入消息轉發機制否則對返回的對象發送消息
5.當觸發消息轉發機制forwardInvocation:方法調用這里的NSInvocation里面包含消息的名字、參數、調用者、返回值等信息
在這里可以調用下面的函數更改消息的調用者
[anInvocation invokeWithTarget:someOthertarget]
[anInvocation selector] //這個獲取方法選擇器
anInvocation參數的由來—在調用forwardInvocation:方法之前runtime會調用methodSignatureForSelector:獲取到返回的方法簽名生成NSInvocation對象所以重寫forwardInvocation:之前也要重寫methodSignatureForSelector:方法否則會拋出異常
NSObject方法中的forwardInvocation:方法只是實現了doesNotRecognizeSelector:方法我們可以實現自己的forwardInvocation:將消息轉發給其他對象
forwardInvocation:這個方法是不能識別的消息的分發中心在這里可以將不能識別的消息轉發給別的對象或者將消息翻譯成另外的消息或者吃掉因此沒有響應也不會報錯
forwardInvocation:這個方法只有在消息的接收對象無法響應的時候才會被調用,否則這個方法不會調用
[self class] , object_getClass(self),object_getClass([self class]),
1.self是實例對象時,[self class]與object_getClass(self)等價,應為前者會調用后者,object_getClass([self class]),返回的是元類
2.self是類對象的時候,[self class],返回的就是本身self ,object_getClass(self)和object_getClass([self class]),是等價的
+(id)Class
{
return self;
}
-(id)class {
return object_getClass(self);
}