ios开发之实现app消息推送(ios推送今日限免app)

简介

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);
}

ios开发之实现app消息推送(ios开发之获取父控制器)ios开发之实现app消息推送(ios开发之获取父控制器)