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); }
声明:如若本站内容侵犯了原著者的合法权益,请提供凭证,可联系我们进行处理,详见<免责声明>