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;
- objc_msgSend:返回值類型根據實際調用方法決定,第一個參數:要調用的方法對象,第二個參數:調用的方法SEL,后面是可變參數,可以根據實際調用的方法參數來決定。
- 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