NSInvocation

本文详细介绍了在iOS开发中如何使用NSInvocation进行动态消息调用,包括基本使用和自定义类的实现,重点突出参数设置、返回值处理及注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在 iOS中可以直接调用某个对象的消息 方式有2种:一种是performSelector:withObject:,再一种就是NSInvocation.

第一种方式比较简单,能完成简单的调用。运行时调用方法都是只接受一个或两个参数,如:

- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;

但是对于大于2个的参数或者有返回值的处理,那就需要做些额外工作才能搞定。那么在这种情况下,我们就可以使用NSInvocation来进行这些相对复杂的操作,NSInvocation可以处理参数、返回值.简单一点理解就是在运行时可以动态决定传入的参数个数,并执行相应的方法.

/**
 *  1:基本使用
 */
-(void)testOne{

    SEL mySelector=@selector(actionInvokeArgumentOne:argTwo:);

    //1:方法签名类:使用NSObject的instance mehtod(也可以使用Class mehtod), 先取得一個NSMethodSignature对象, 並创建一個NSInvocation.被调用的消息actionInvokeArgumentOne:argTwo:.

    NSMethodSignature *signature=[self methodSignatureForSelector:mySelector];
    NSInvocation *invocation=[NSInvocation invocationWithMethodSignature:signature];

    //2:這时取得的invocation只有简单的method可帶入的argument數量, 在正式調用之前你還需要設定target跟selector.
    [invocation setTarget:self];
    [invocation setSelector:mySelector];

    //3设置参数
    NSInteger argOne = 10;
    NSNumber *argTwo = @20;

    /*
      第一个参数:需要给指定方法传递的值,第一个参数需要接收一个指针,也就是传递值的时候需要传递地址
      第二个参数:需要给指定方法的第几个参数传值
     */
    [invocation setArgument:&argOne atIndex:2];
    [invocation setArgument:&argTwo atIndex:3];

    //4:消息调用
    [invocation invoke];

    /*
     注意点:

     1:NSInvocation的使用有一個地方要特別注意, invocation不能使用 alloc跟init來建立对象, 只能使用invocationWithMethodSignature:來建立对象.
     2:使用Invocation, method所帶入的参數也不用都转成object, int、BOOL都可以使用.
     3:NSMethodSignature的numberOfArguments最小值是2; 0跟1是給预设的隱藏参數使用(self & _cmd).

     */
}

-(void)actionInvokeArgumentOne:(NSInteger)argOne argTwo:(NSNumber *)argTwo{

     NSLog(@"action: arg1 + arg2= %d", argOne + [argTwo integerValue]);
    // NSInvocation[10080:1915122] action: arg1 + arg2=30
}
/**
 *   2:自定义类的使用
 */
-(void)testTwo{

     SHClass *class=[[SHClass alloc]init];
     NSString *myString = @"My string";

    //普通调用
    NSString *normalInvokeString=[class appendMyString:myString];
    NSLog(@"The normal invoke string is: %@", normalInvokeString);

    //NSInvocation调用
    SEL mySelector = @selector(appendMyString:);
    NSMethodSignature * sig = [[SHClass class]
                               instanceMethodSignatureForSelector: mySelector];

    NSInvocation * myInvocation = [NSInvocation invocationWithMethodSignature: sig];
    [myInvocation setTarget: class];
    [myInvocation setSelector: mySelector];

    [myInvocation setArgument: &myString atIndex: 2];

    NSString * result = nil;
    [myInvocation retainArguments];
    [myInvocation invoke];
    [myInvocation getReturnValue: &result];

    NSLog(@"The NSInvocation invoke string is: %@", result);
    // The NSInvocation invoke string is: My string after append method

}
#import <Foundation/Foundation.h>

@interface SHClass : NSObject

-(NSString *)appendMyString:(NSString *)string;

@end

#import "SHClass.h"

@implementation SHClass

- (id)init
{
    self = [super init];
    if (self) {
        // Initialization code here.
    }

    return self;
}

-(NSString *)appendMyString:(NSString *)string
{
    NSString *mString = [NSString stringWithFormat:@"%@ after append method", string];
    // The normal invoke string is: My string after append method
    return mString;
}
@end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值