在 iOS中可以直接调用 某个对象的消息 方式有2种
- performSelector:withObject:
- NSInvocation
第一种方式比较简单,能完成简单的调用。但是对于>2个的参数或者有返回值的处理,处理就相当麻烦。
第二种NSInvocation也是一种消息调用的方法,并且它的参数没有限制,可以处理参数、返回值等相对复杂的操作。
1.初始化使用
-
无参数无返回值
- (void)invocation{ //根据方法创建签名对象sig NSMethodSignature *sign = [[self class] instanceMethodSignatureForSelector:@selector(method)]; // 根据签名对象创建调用对象invocation NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sign]; //设置target invocation.target = self; //设置selector invocation.selector = @selector(method); //消息调用 [invocation invoke]; } - (void)method { NSLog(@"method被调用"); }
有参数无返回值
- (void)invocation{
//根据方法创建签名对象sig
NSMethodSignature *sign = [[self class] instanceMethodSignatureForSelector:@selector(sendMessage:name:)];
//根据签名对象创建invocation
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sign];
//设置调用对象的相关信息
NSString *name = @"张三";
NSString *message = @"发送一条消息";
//参数必须从第2个索引开始,因为前两个已经被target和selector使用
[invocation setArgument:&name atIndex:2];
[invocation setArgument:&message atIndex:3];
invocation.target = self;
invocation.selector = @selector(sendMessage:name:);
//消息调用
[invocation invoke];
}
- (void)sendMessage:(NSString*)message name:(NSString*)name{
NSLog(@"%@ %@",name,message);
}
-
有参数有返回值
- (void)invocation{ //根据方法创建签名对象sig NSMethodSignature *sign = [[self class] instanceMethodSignatureForSelector:@selector(sumNumber1:number2:)]; //根据签名创建invocation NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sign]; //设置调用对象相关信息 invocation.target = self; invocation.selector = @selector(sumNumber1:number2:); NSInteger number1 = 30; NSInteger number2 = 10; [invocation setArgument:&number1 atIndex:2]; [invocation setArgument:&number2 atIndex:3]; //消息调用 [invocation invoke]; //获取返回值 NSNumber *sum = nil; [invocation getReturnValue:&sum]; NSLog(@"总和==%zd",[sum integerValue]); } - (NSNumber*)sumNumber1:(NSInteger)number1 number2:(NSInteger)number2{ NSInteger sum = number1+number2; return @(sum); }
2.常见方法及属性
- NSInvocation其他常见方法属性
//保留参数,它会将传入的所有参数以及target都retain一遍
- (void)retainArguments
// 判断参数是否存在,调用retainArguments之前,值为NO,调用之后值为YES
@property (readonly) BOOL argumentsRetained;
// 设置消息返回值
- (void)setReturnValue:(void *)retLoc;
- NSMethodSignature其他常见方法属性
// 方法参数个数
@property (readonly) NSUInteger numberOfArguments;
// 获取方法的长度
@property (readonly) NSUInteger frameLength;
// 是否是单向
- (BOOL)isOneway;
// 获取方法返回值类型
@property (readonly) const char *methodReturnType NS_RETURNS_INNER_POINTER;
// 获取方法返回值的长度
@property (readonly) NSUInteger methodReturnLength;