OC中的消息轉(zhuǎn)發(fā)過程

消息轉(zhuǎn)發(fā)

描述:如果類不能執(zhí)行這個方法,會執(zhí)行動態(tài)消息轉(zhuǎn)發(fā),如果該類還是不能動態(tài)的添加方法,則走完整的消息轉(zhuǎn)發(fā)。分兩步,第一步看看有沒有其他類可以執(zhí)行該方法,如果沒有走第二步,將所有的細(xì)節(jié)封裝到NSInvocation中,給接受者最后一次機會。

演示:

動態(tài)消息轉(zhuǎn)發(fā)

在一個類MessageObj中定義兩個方法,testDynamicMethodForward一個有實現(xiàn)方法,start一個沒有實現(xiàn)的方法,調(diào)用沒有實現(xiàn)的方法,在動態(tài)消息轉(zhuǎn)發(fā)的時候?qū)⑦@個方法hook到已經(jīng)實現(xiàn)的方法上:

@interface MessageObj()
@end


@implementation MessageObj

//-(void)start{}
void testDynamicMethodForward(){
    printf("testDynamicMethodForward \n");
}

+(BOOL)resolveInstanceMethod:(SEL)sel {
    class_addMethod([self class], sel, (IMP)testDynamicMethodForward, "v@@:");
    return YES;
}
@end

打印如下:testDynamicMethodForward

完整的消息轉(zhuǎn)發(fā)第一步

定義兩個類,第一個類MessageObj有一個未實現(xiàn)的方法start,并且沒有實現(xiàn)動態(tài)消息轉(zhuǎn)發(fā)。第二個類OtherClass,有一個和第一個類中未實現(xiàn)的方法同名的方法start,在進行完整消息轉(zhuǎn)發(fā)的第一步時,將MessageObj中未實現(xiàn)的方法hook到,OtherClass的同名方法start

OtherClass類

@interface OtherClass : NSObject

@end

@implementation OtherClass

-(void)start{
    NSLog(@"do some thing %@",[self class]);
}

@end

MessageObj類

@implementation MessageObj

//-(void)start{}

-(id)forwardingTargetForSelector:(SEL)aSelector {
    printf("%p \n",&aSelector);
    OtherClass *obj = [OtherClass new];
    return obj;
}

調(diào)用start方法

MessageObj *obj = [MessageObj new];
[obj start];

打?。篸o some thing OtherClass

完整消息轉(zhuǎn)發(fā)的第二步

如果以上兩步都失敗了,就走到這里。定義兩個類MessageObj、OtherClassMessageObj中存在OtherClass的實例。當(dāng)走到消息轉(zhuǎn)發(fā)的第三步時,先進行方法重簽名-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector,再走最后的消息轉(zhuǎn)發(fā)-(void)forwardInvocation:(NSInvocation *)anInvocation。

OtherClass類

@interface OtherClass : NSObject

@end
@implementation OtherClass

-(void)start{
    NSLog(@"message transform third part %@",[self class]);
}

@end

MessageObj類

@implementation MessageObj


-(instancetype)init {
    if (self = [super init]) {
        otherClass = [OtherClass new];
    }
    return  self;
}


//-(void)start{}
//方法重簽名
-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    NSMethodSignature *signature = [super methodSignatureForSelector:aSelector];
    if (!signature) {
        signature = [otherClass methodSignatureForSelector:aSelector];
    }
    return signature;
}
//最后的消息轉(zhuǎn)發(fā)
-(void)forwardInvocation:(NSInvocation *)anInvocation {
    if (!otherClass) {
        [self doesNotRecognizeSelector:[anInvocation selector]];
    }
    [anInvocation invokeWithTarget:otherClass];
}

打印:message transform third part OtherClass

用途:

  • 在方法不能識別的時候做一些保護,防止crash
  • 調(diào)試的時候打印一些感興趣的日志
  • 也可以hook系統(tǒng)的方法玩玩呀
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,041評論 0 9
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,534評論 19 139
  • 目錄 Objective-C Runtime到底是什么 Objective-C的元素認(rèn)知 Runtime詳解 應(yīng)用...
    Ryan___閱讀 2,008評論 1 3
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,872評論 25 709
  • 一、項目名稱:筑塔 二、項目類型:管理游戲 三、項目要求:由至少兩個,或兩個以上的團隊完成,每個隊有7人 四、項目...
    騎著火箭追流星閱讀 2,863評論 0 2

友情鏈接更多精彩內(nèi)容