最近在訪問私有方法的時候剃袍,多于2個參數(shù)黄刚,因此使用NSInvocation。
一開始民效,私有方法返回值是int, 如下圖:
-(int)xxxx:(int)val vv:(int)vv xx:(int)xx {}
考慮到如果每一種返回值類型都要更新處理隘击,這想想都麻煩。
因此研铆,用NSObject添加分類埋同。
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSObject (Ext)
- (id)textInvocation:(SEL)selector block:(void (^)(NSInvocation *))block;
@end
NS_ASSUME_NONNULL_END
#import "NSObject+Ext.h"
@implementation NSObject (Ext)
- (id)textInvocation:(SEL)selector block:(void (^)(NSInvocation *))block {
NSMethodSignature *sig = [self methodSignatureForSelector:selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];
// 設(shè)置參數(shù)
invocation.target = self;
invocation.selector = selector;
block(invocation);
// 設(shè)置返回值
id result = nil;
// 檢查方法返回類型
const char *returnType = sig.methodReturnType;
if (strcmp(returnType, @encode(void)) == 0) {
// 返回類型為 void,無需處理
[invocation invoke];
} else if (strcmp(returnType, @encode(id)) == 0) {
// 返回類型為對象類型
[invocation invoke];
[invocation getReturnValue:&result];
} else if (strcmp(returnType, @encode(NSInteger)) == 0) {
// 返回類型為 NSInteger
NSInteger value = 0;
[invocation invoke];
[invocation getReturnValue:&value];
result = @(value); // 封裝為 NSNumber
} else if (strcmp(returnType, @encode(float)) == 0) {
// 返回類型為 float
float value = 0.0f;
[invocation invoke];
[invocation getReturnValue:&value];
result = @(value); // 封裝為 NSNumber
} else if (strcmp(returnType, @encode(double)) == 0) {
// 返回類型為 double
double value = 0.0;
[invocation invoke];
[invocation getReturnValue:&value];
result = @(value); // 封裝為 NSNumber
} else {
// 其他基本數(shù)據(jù)類型棵红,你可以根據(jù)需要繼續(xù)擴(kuò)展
}
return result;
}
@end
//調(diào)用方法示例
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NSLog(@"金額:%@",[[Person new] textInvocation:@selector(dataCount:vv:cc:) block:^(NSInvocation * _Nonnull invocation) {
NSNumber *num = [NSNumber numberWithInt:1];
NSNumber *num1 = [NSNumber numberWithInt:2];
NSNumber *num2 = [NSNumber numberWithInt:2];
[invocation setArgument:&num atIndex:2];
[invocation setArgument:&num1 atIndex:3];
[invocation setArgument:&num2 atIndex:4];
} ]);
}
通過這樣的方式凶赁, 需要的參數(shù),通過閉包中NSInvocation處理,類型統(tǒng)一在分類中處理虱肄。