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];
}