performselector(performselector 返回值 内存泄露)

iOS开发之-NSInvocation

简介

Objective-C 是动态语言,所有的消息都是在 Runtime 进行派发的。

最底层的转发函数为objc_msgSend。

使用 performSelector 可以给对象发送消息,但是其有几个短板

在 ARC 场景下 performSelector 可能会造成内存泄漏performSelector 至多接收 2 个参数,如果参数多余 2 个,我们就无法使用 performSelector 来向对象发送消息了。performSelector 限制参数类型为 id,以标量数据(int double NSInteger 等)为参数的方法使用 performSelector 调用会出现各种各样诡异的问题

NSInvocation 是苹果工程师们提供的一个高层的消息转发系统。它是一个命令对象,是一个消息调用类,可以给任何 Objective-C 对象类型发送消息。

NSInvocation 包含了所有OC消息的成分:target、selector、参数、返回值等。NSInvocation可以将消息转换成一个对象,消息的每一个参数能够直接设定,而且当一个NSInvocation对象调度时返回值是可以自己设定的。一个NSInvocation对象能够重复的调度不同的目标(target),而且它的selector也能够设置为另外一个方法签名。

NSInvocation 的使用

使用步骤:

创建方法创建签名对象NSMethodSignature
根据签名对象创建调用NSInvocation
设置调用对象相关信息
调用方法
获取返回值
无参数、无返回值

无参数、无返回值 的 对应代码为:

– (void)startTest_Imple
{
// 获取方法签名
NSMethodSignature *signature = [[self class] instanceMethodSignatureForSelector:@selector(startTest)];
// 生成调用对象
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
// 设置target
invocation.target = self;
// 设置方法实现
invocation.selector = @selector(startTest);
// 调用
[invocation invoke];
}

– (void)startTest
{
NSLog(@”无参数、无返回值:startTest_1″);
}

两个个参数、有返回值的代码为:

– (void)startTest_Imple_3
{
// 获取方法签名
NSMethodSignature *signature = [ViewController instanceMethodSignatureForSelector:@selector(startTest_3:text1:)];
// 生成调用对象
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
// 设置target
invocation.target = self;
// 设置方法实现
invocation.selector = @selector(startTest_3:text1:);
// 设置参数,参数必须从2开始,第一个第二个参数为target和selector
NSString *argument = @”参数1″;
NSString *argument1 = @”参数2″;
[invocation setArgument:&argument atIndex:2];
[invocation setArgument:&argument1 atIndex:3];
// 调用
[invocation invoke];
NSString *returnValue = nil;
[invocation getReturnValue:&returnValue];
NSLog(@”返回值:%@”,returnValue);
}
– (NSString *)startTest_3:(NSString *)text text1:(NSString *)text1
{
NSLog(@”参数%@–%@,无返回值:startTest_1″,text,text1);
return @”返回值”;
}

具体实例,下面用NSInvocation方式来调用sendMessageWithnumber方法。

– (void)viewDidLoad {
[super viewDidLoad];
//NSInvocation;用来包装方法和对应的对象,它可以存储方法的名称,对应的对象,对应的参数,
/*
NSMethodSignature:签名:再创建NSMethodSignature的时候,必须传递一个签名对象,签名对象的作用:用于获取参数的个数和方法的返回值
*/
//创建签名对象的时候不是使用NSMethodSignature这个类创建,而是方法属于谁就用谁来创建
NSMethodSignature*signature = [ViewController instanceMethodSignatureForSelector:@selector(sendMessageWithNumber:WithContent:)];

//1、创建NSInvocation对象
NSInvocation*invocation = [NSInvocation invocationWithMethodSignature:signature];

invocation.target = self;

//invocation中的方法必须和签名中的方法一致。
invocation.selector = @selector(sendMessageWithNumber:WithContent:);

/*第一个参数:需要给指定方法传递的值
第一个参数需要接收一个指针,也就是传递值的时候需要传递地址*/
//第二个参数:需要给指定方法的第几个参数传值
NSString*number = @”1111″;

//注意:设置参数的索引时不能从0开始,因为0已经被self占用,1已经被_cmd占用
[invocation setArgument:&number atIndex:2];

NSString*number2 = @”啊啊啊”;

[invocation setArgument:&number2 atIndex:3];

//2、调用NSInvocation对象的invoke方法
//只要调用invocation的invoke方法,就代表需要执行NSInvocation对象中制定对象的指定方法,并且传递指定的参数
[invocation invoke];
}
– (void)sendMessageWithNumber:(NSString*)number WithContent:(NSString*)content{
NSLog(@”电话号%@,内容%@”,number,content);
}

performselector(performselector 返回值 内存泄露)

本文来自胡巴网投稿,不代表胡巴网立场,如若转载,请注明出处:https://www.hu85.com/343313.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 xxxxx@qq.com 举报,一经查实,本站将立刻删除。