首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Objective-C 消息機制全流程解析:從 objc_msgSend 到消息轉發

     編輯:關於C語言

Objective-C 消息機制全流程解析:從 objc_msgSend 到消息轉發

Objective-C 採用動態消息分發,方法調用最終轉為 objc_msgSend(receiver, selector, args...)。運行時經歷多級查找與救援機制,保證極高的動態性。

標準查找流程

  1. 快速路徑:若 selector 為 retain/release/retainCount 等內存管理方法,直接返回接收者。
  2. 空接收者保護:receiver == nil 直接返回 0/nil/結構體零值。
  3. 緩存查找:在類的 方法緩存(哈希表)中查找 selector,命中則直接跳轉 IMP 執行。
  4. 方法列表遍歷:未命中緩存,遍歷類的 方法列表,找到則填入緩存並執行。
  5. 父類遞歸查找:沿繼承鏈向上查找,直到 NSObject。

三級消息救援機制

1. 動態方法解析 +resolveInstanceMethod:

類可在運行時動態添加方法實現:

+ (BOOL)resolveInstanceMethod:(SEL)sel {
    if ([NSStringFromSelector(sel) isEqualToString:@"makeSomeFood:"]) {
        class_addMethod([Man class], sel, (IMP)makeVegetable, "v@:@");
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}

適用於「懶加載」方法實現,如 Core Data 動態生成存取器。

2. 備用接收者 -forwardingTargetForSelector:

將消息轉發給其他對象處理(如代理模式):

- (id)forwardingTargetForSelector:(SEL)aSelector {
    if ([_wife respondsToSelector:aSelector]) return _wife;
    return [super forwardingTargetForSelector:aSelector];
}

新接收者同樣會經歷完整查找流程。

3. 完整消息轉發 -methodSignatureForSelector: + -forwardInvocation:

構造 NSInvocation 封裝完整調用信息,交由任意目標處理:

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    NSMethodSignature *sig = [super methodSignatureForSelector:aSelector];
    if (!sig && [RichFriend instancesRespondToSelector:aSelector])
        sig = [RichFriend instanceMethodSignatureForSelector:aSelector];
    return sig;
}
- (void)forwardInvocation:(NSInvocation *)inv {
    if ([RichFriend instancesRespondToSelector:inv.selector])
        [inv invokeWithTarget:[RichFriend new]];
    else
        [super forwardInvocation:inv];
}

此階段可修改參數、返回值,實現極靈活的 AOP、遠程調用等。

最終失敗

若所有救援失敗,NSObject 的 forwardInvocation: 拋出 doesNotRecognizeSelector: 異常,程序崩潰。

總結

Objective-C 消息機制通過「緩存→列表→父類→動態解析→轉發目標→完整轉發」的層層遞進,實現了極致的動態性,也是 Cocoa 框架靈活性的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved