iOS直接調(diào)用對象方法的消息方式

1、performSelector

NSClassFromString 與 NSSelectorFromString
執(zhí)行 performSelector:withObject


2、NSInvocation

// NSInvocation中保存了方法所屬的對象/方法名稱/參數(shù)/返回值

//其實NSInvocation就是將一個方法變成一個對象

//2、創(chuàng)建NSInvocation對象

NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];

//設(shè)置方法調(diào)用者

invocation.target = self;

//注意:這里的方法名一定要與方法簽名類中的方法一致

invocation.selector = @selector(do:);
NSString *method = @"goHome";

//這里的Index要從2開始,以為0跟1已經(jīng)被占據(jù)了,分別是self(target),selector(_cmd)

[invocation setArgument:&way atIndex:2];

//3、調(diào)用invoke方法

[invocation invoke];

//實現(xiàn)run:方法

- (void)do:(NSString *)method{}


優(yōu)化點

方法的參數(shù)個數(shù)與外界傳進來的參數(shù)數(shù)組元素個數(shù)不符

//此處不能通過遍歷參數(shù)數(shù)組來設(shè)置參數(shù),因為外界傳進來的參數(shù)個數(shù)是不可控的
//因此通過numberOfArguments方法獲取的參數(shù)個數(shù),是包含self和_cmd的,然后比較方法需要的參數(shù)和外界傳進來的參數(shù)個數(shù),并且取它們之間的最小值
NSUInteger argsCount = signature.numberOfArguments - 2;
NSUInteger arrCount = objects.count;
NSUInteger count = MIN(argsCount, arrCount);
for (int i = 0; i < count; i++) {
? ?id obj = objects[i];
? ?// 判斷需要設(shè)置的參數(shù)是否是NSNull, 如果是就設(shè)置為nil
? ?if ([obj isKindOfClass:[NSNull class]]) {
? ? ? ?obj = nil;
? ?}
[invocation setArgument:&obj atIndex:i + 2];
}
最后編輯于
?著作權(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)容

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