objc_msgSend和objc_msgSendSuper的使用


objc_msgSend:用於對objc對象發送消息,執行objc的方法。

objc_msgSendSuper:同上一樣,這里是調用objc父類對象的方法。

使用以上函數之前需要對它們做函數轉換后,方可使用,以下是這些函數的注釋

These functions must be cast to an appropriate function pointer type before being called.

意思就是:在調用這些函數之前,必須將它們轉換為適當的函數指針類型。根據開發文檔中的描述我們可知,以上函數對應的描述如下:

OBJC_EXPORT id _Nullable
objc_msgSend(id _Nullable self, SEL _Nonnull op, ...)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

OBJC_EXPORT id _Nullable
objc_msgSendSuper(struct objc_super * _Nonnull super, SEL _Nonnull op, ...)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

/// Specifies the superclass of an instance. 

struct objc_super {

    /// Specifies an instance of a class.

    __unsafe_unretained _Nonnull id receiver;

 

    /// Specifies the particular superclass of the instance to message. 

#if !defined(__cplusplus)  &&  !__OBJC2__

    /* For compatibility with old objc-runtime.h header */

    __unsafe_unretained _Nonnull Class class;// 這里是兼容舊版本的objc-runtime.h

#else

    __unsafe_unretained _Nonnull Class super_class;

#endif

    /* super_class is the first class to search */

};

#endif

這樣我們就可以將上面的兩個函數轉換成如下函數指針:

id (*sendMsg)(id, SEL) = (void *)objc_msgSend;
id (*sendMsgSuper)(void *, SEL) = (void *)objc_msgSendSuper;
  1. objc_msgSend:返回值類型根據實際調用方法決定,第一個參數:要調用的方法對象,第二個參數:調用的方法SEL,后面是可變參數,可以根據實際調用的方法參數來決定。
  2. objc_msgSendSuper:返回值類型根據實際調用方法決定,第一個參數:objc_super的struct對象指針,第二個參數:調用的方法SEL,后面是可變參數,可以根據實際調用的方法參數來決定。

事例代碼:

 1 @interface BaseObj : NSObject
 2 
 3 - (int)add:(int)a b:(int)b;
 4 
 5 @end
 6 @implementation BaseObj
 7 
 8 - (int)add:(int)a b:(int)b{
 9     return a+b;
10 }
11 
12 @end
13 
14 @interface MyObj : BaseObj
15 
16 @end
17 
18 // 利用runtime調用MyObj父類的add方法
19 MyObj *obj = [[MyObj alloc] init];
20 
21 Class cls = object_getClass(obj);
22 Class superCls = class_getSuperclass(cls);
23 
24 struct objc_super obj_super_class = {
25         .receiver = obj,
26         .super_class = superCls
27     };
28 
29 // 將objc_msgSendSuper轉換成對應的函數指針
30 int (*add)(void *, SEL, int, int) = (void *)objc_msgSendSuper;
31 // 調用add方法,&操作符是c/c++取指針的操作符
32 int i = add(&obj_super_class, @selector(add:b:), 1, 2); // 這里的返回值類型根據實際調用方法可知,是一個int類型
33 NSLog(@"1+2=%@", @(i));

輸出如下:

2020-02-19 20:48:23.524429+0800 Test[1331:133221] 1+2=3

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM