消息機(jī)制(消息發(fā)送、動(dòng)態(tài)解析、消息重定向)

第一步、消息發(fā)送

#import <objc/message.h>

    // 創(chuàng)建person對象
    person *p = [[person alloc] init];

    // 調(diào)用對象方法
    [p eat];

    // 本質(zhì):讓對象發(fā)送消息(對象方法)
    objc_msgSend(p, @selector(eat));

    // 本質(zhì):讓類對象發(fā)送消息(類方法)
    objc_msgSend([person class], @selector(sleep));

第二步、動(dòng)態(tài)解析

第三步、消息重定向

屏幕快照 2020-07-27 上午11.37.52.png
- (void)viewDidLoad {

    [super viewDidLoad];

    [self performSelector:@selector(eat)];

}

/***第一次、動(dòng)態(tài)解析***/
+(BOOL)resolveInstanceMethod:(SEL)sel
{

    if (sel == @selector(eat)) {

        class_addMethod([self class], sel, (IMP)funMethod, "v@:");

    }

    return YES;

}

void funMethod(id obj,SEL _cmd) {

    NSLog(@"funMethod"); //新的 fun 函數(shù)

}

/***第二次、接受者消息重定向***/
- (id)forwardingTargetForSelector:(SEL) aSelector
{

    if (aSelector == @selector(eat)) {

        person * p = [[person alloc]init];

        return p;

    }

    return nil;

}

/***第三次、獲取函數(shù)的參數(shù)和返回值類型,返回簽名***/
- (NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector {
    if ([NSStringFromSelector(aSelector) isEqualToString:@"eat"]) {

        return [NSMethodSignature signatureWithObjCTypes:"v@:"];

    }

    return [super methodSignatureForSelector:aSelector];

}

/***第三次、消息重定向***/
- (void)forwardInvocation:(NSInvocation*)anInvocation {
    SEL sel = anInvocation.selector;  // 從 anInvocation 中獲取消息

    person * p = [[person alloc]init];

    if([p respondsToSelector:sel]) {  // 判斷 Person 對象方法是否可以響應(yīng) sel

        [anInvocation invokeWithTarget:p];  // 若可以響應(yīng),則將消息轉(zhuǎn)發(fā)給其他對象處理

    }else{

        [self doesNotRecognizeSelector:sel];  // 若仍然無法響應(yīng),則報(bào)錯(cuò):找不到響應(yīng)方法

    }

}

@end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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