NSMethodSignature 顾名思义应该就是“方法签名”,类似于C++中的编译器时的函数签名。苹果官方定义该类为对方法的参数、返回类似进行封装,协同NSInvocation实现消息转发。通过消息转发实现类似C++中的多重继承;
NSMethodSignature 主要提供了一下功能:
- 1、方法参数个数
- 2、方法参数类型
- 3、方法返回值类型
签名方法的生成
我们可以通过类的实例方法或者类方法获取该类下的(SEL)aSelector 的方法签名
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector OBJC_SWIFT_UNAVAILABLE("");
+ (NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)aSelector OBJC_SWIFT_UNAVAILABLE("");
通过实例获取某一个方法签名:
NSMethodSignature* methodSig = [[[someClass alloc] init] methodSignatureForSelector:action];
通过类获取某一个方法签名:
NSMethodSignature *sig = [[someClass class] instanceMethodSignatureForSelector:myMethod];
获取方法参数个数及类型
NSUInteger argCount = [sig numberOfArguments];
NSLog(@"argCount:%ld", argCount);
for (NSInteger i=0; i<argCount; i++) {
NSLog(@"%s", [sig getArgumentTypeAtIndex:i]);
}
作者:城市之光
链接:https://www.jianshu.com/p/7e2efff789e2
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
获取方法签名的返回值类型
并且我们可以通过
@property (readonly) const char *methodReturnType NS_RETURNS_INNER_POINTER;
从而完成
#pragma mark - private methods
- (id)safePerformAction:(SEL)action target:(NSObject *)target params:(NSDictionary *)params
{
NSMethodSignature* methodSig = [target methodSignatureForSelector:action];
if(methodSig == nil) {
return nil;
}
const char* retType = [methodSig methodReturnType];
//返回void 类型
if (strcmp(retType, @encode(void)) == 0) {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
[invocation setArgument:¶ms atIndex:2];
[invocation setSelector:action];
[invocation setTarget:target];
[invocation invoke];
return nil;
}
//返回NSInteger 类型
if (strcmp(retType, @encode(NSInteger)) == 0) {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
[invocation setArgument:¶ms atIndex:2];
[invocation setSelector:action];
[invocation setTarget:target];
[invocation invoke];
//获取到方法返回值
NSInteger result = 0;
[invocation getReturnValue:&result];
return @(result);
}
if (strcmp(retType, @encode(BOOL)) == 0) {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
[invocation setArgument:¶ms atIndex:2];
[invocation setSelector:action];
[invocation setTarget:target];
[invocation invoke];
//获取到方法返回值
BOOL result = 0;
[invocation getReturnValue:&result];
return @(result);
}
if (strcmp(retType, @encode(CGFloat)) == 0) {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
[invocation setArgument:¶ms atIndex:2];
[invocation setSelector:action];
[invocation setTarget:target];
[invocation invoke];
//获取到方法返回值
CGFloat result = 0;
[invocation getReturnValue:&result];
return @(result);
}
if (strcmp(retType, @encode(NSUInteger)) == 0) {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
[invocation setArgument:¶ms atIndex:2];
[invocation setSelector:action];
[invocation setTarget:target];
[invocation invoke];
//获取到方法返回值
NSUInteger result = 0;
[invocation getReturnValue:&result];
return @(result);
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
return [target performSelector:action withObject:params];
#pragma clang diagnostic pop
}
网友评论