OC 动态库的调用包括动态设置属性值,调用方法,设置代理实现代理方法
2016-09-18 14:44
399 查看
最近做了个动态更新模块的功能,是使用动态库来完成的。因为要求动态更新所以就不方便引入头文件了这里就只好采用动态调用动态库的方法了。具体包含以下几个方面:创建对象并设置属性值,调用对象的方法这个方法包括类方法(静态方法)和对象方法,设置对象的代理并实现代理方法。
在一切开始之前我们要先加载动态库这个在前面的博客中有说明的感兴趣的可以去看看。
首先创建对象这个很简单OC中有个方法
对象创建出来了我们要给它赋值,这里我采用的方法是再创建一个类FanWeiPayParam,这个类的属性跟FWPayParam一样然后我们通过对象直接赋值,接下来看具体实现:
我们先获取FanWeiPayParam的属性和属性值然后通过
属性值设置到这里就完成了,因为代理通常都是作为一个对象属性的比如:
我们可以采用上面的方法直接给它设置这个属性值,也可以把这个代理属性作为一个函数的传入参数,这个稍后再说。
调用动态库里面的方法我们首先也需要通过类名获取类,在OC里面方法有两种类型一种是类方法类似于其他语言里面的静态方法,还有一种是对象方法。在oc里面对象方法是由对象调用的,类方法是由类调用的但同时我们又常说类也是一个对象它是类对象所以在这里调用动态库的方法时我们都使用下面几个方法无论它是类方法或者是对象方法区别只在于如果是对象方法要先创建一个对象,类方法无需创建对象。
第一个传入参数是SEL类型的值表示将要调用的函数,后面如果有值都表示将要调用的函数的参数。具体的实现如下:
接下来看完整的调用吧:
上面最后一个参数self就是我们设置的代理对象,至于我们要实现的代理方法直接在代理对象里面实现就可以了,原因很简单我们在使用代理的时候一般都先判断代理对象里面有没有实现代理方法了,如果实现了再使用代理对象调用代理方法。还有下面这种调用:
下面是封装好的动态库调用的代码.h文件
下面是.m文件
限于笔者水平有限这里面会有很多错漏的地方在此抛砖引玉欢迎大家指正。
在一切开始之前我们要先加载动态库这个在前面的博客中有说明的感兴趣的可以去看看。
首先创建对象这个很简单OC中有个方法
NSClassFromString(NSString *aClassName),官方解释为:Obtains a class by name,通过类名获取类。然后我们可以通过类创建对象了,这个创建出来的对象是id类型的。
Class FWPayParam = NSClassFromString(className); _param = [[FWPayParam alloc] init];
对象创建出来了我们要给它赋值,这里我采用的方法是再创建一个类FanWeiPayParam,这个类的属性跟FWPayParam一样然后我们通过对象直接赋值,接下来看具体实现:
- (void)copy:(id)payParam { //定义无符号int类型 unsigned int outCount,count; //获取包含指定类公开的属性名地址(不包括这个类的父类属性)的数组,outCount数组长度 objc_property_t *property = class_copyPropertyList([self class], &outCount); //遍历数组 for (count = 0; count<outCount; count++) { objc_property_t t = property[count]; //获取属性名 NSString *key = [NSString stringWithUTF8String:property_getName(t)]; //获取属性名对应的属性值 id value = [self valueForKey:key]; //设置属性和属性值 [payParam setValue:value forKey:key]; } free(property); }
我们先获取FanWeiPayParam的属性和属性值然后通过
- (void)setValue:(nullable id)value forKey:(NSString *)key这个方法设置属性值。
属性值设置到这里就完成了,因为代理通常都是作为一个对象属性的比如:
@property (nonatomic,weak) id<FWManagerDelegate> delegate
我们可以采用上面的方法直接给它设置这个属性值,也可以把这个代理属性作为一个函数的传入参数,这个稍后再说。
调用动态库里面的方法我们首先也需要通过类名获取类,在OC里面方法有两种类型一种是类方法类似于其他语言里面的静态方法,还有一种是对象方法。在oc里面对象方法是由对象调用的,类方法是由类调用的但同时我们又常说类也是一个对象它是类对象所以在这里调用动态库的方法时我们都使用下面几个方法无论它是类方法或者是对象方法区别只在于如果是对象方法要先创建一个对象,类方法无需创建对象。
- (id)performSelector:(SEL)aSelector; - (id)performSelector:(SEL)aSelector withObject:(id)object; - (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
第一个传入参数是SEL类型的值表示将要调用的函数,后面如果有值都表示将要调用的函数的参数。具体的实现如下:
- (void)thisClass:(NSString *)className performSelector:(NSString *)meth withObject:(id)object1 withObject:(id)object2 { Class FWPay = NSClassFromString(className); if ([FWPay respondsToSelector:NSSelectorFromString(meth)]) { if (object1 != nil && object2 != nil) { [FWPay performSelector:NSSelectorFromString(meth) withObject:object1 withObject:object2]; return; } if (object1 != nil && object2 == nil) { [FWPay performSelector:NSSelectorFromString(meth) withObject:object1]; return; } if (object1 == nil && object2 == nil) { [FWPay performSelector:NSSelectorFromString(meth)]; return; } } }
接下来看完整的调用吧:
FWInvoke *invoke = [[FWInvoke alloc] initWithParamClass:@"FWPayParam"]; [payParam copy:invoke.param]; [invoke thisClass:@"FWPay" performSelector:@"startPay:delegate:" withObject:invoke.param withObject:self];
上面最后一个参数self就是我们设置的代理对象,至于我们要实现的代理方法直接在代理对象里面实现就可以了,原因很简单我们在使用代理的时候一般都先判断代理对象里面有没有实现代理方法了,如果实现了再使用代理对象调用代理方法。还有下面这种调用:
FWInvoke *invoke = [[FWInvoke alloc] init]; [invoke thisClass:@"FWPay" performSelector:@"applicationWillEnterForeground:" withObject:application withObject:nil];
下面是封装好的动态库调用的代码.h文件
#import <Foundation/Foundation.h> @interface FWInvoke : NSObject @property (nonatomic,strong) id param; - (instancetype)initWithParamClass:(NSString *)className; -(void)thisClass:(NSString *)className performSelector:(NSString *)meth withObject:(id)object1 withObject:(id)object2; @end
下面是.m文件
#import "FWInvoke.h"
@implementation FWInvoke
- (instancetype)initWithParamClass:(NSString *)className {
self = [super init];
if (self) {
if (className != nil) {
Class FWPayParam = NSClassFromString(className); _param = [[FWPayParam alloc] init];
}
}
return self;
}
- (void)thisClass:(NSString *)className performSelector:(NSString *)meth withObject:(id)object1 withObject:(id)object2 { Class FWPay = NSClassFromString(className); if ([FWPay respondsToSelector:NSSelectorFromString(meth)]) { if (object1 != nil && object2 != nil) { [FWPay performSelector:NSSelectorFromString(meth) withObject:object1 withObject:object2]; return; } if (object1 != nil && object2 == nil) { [FWPay performSelector:NSSelectorFromString(meth) withObject:object1]; return; } if (object1 == nil && object2 == nil) { [FWPay performSelector:NSSelectorFromString(meth)]; return; } } }@end
限于笔者水平有限这里面会有很多错漏的地方在此抛砖引玉欢迎大家指正。
相关文章推荐
- java反射机制(2)- 实践:反射机制+动态代理实现模拟RMI远程方法调用
- spring动态代理的实现原理InvocationHandler中invoke()方法的调用问题
- Java使用注解和动态代理实现方法调用时的日志记录示例
- Java动态代理实现模拟RMI远程方法调用
- Java动态代理的两种实现方法
- Struts2.5使用通配符的方式实现动态方法调用报错
- Java动态代理的两种实现方法
- Python实现爬虫设置代理IP和伪装成浏览器的方法分享
- Java 动态代理 两种实现方法
- js 获取和设置css3 属性值的实现方法
- 基于JDK动态代理实现的接口链式调用(Fluent Interface)工具
- iOS开发之OC与swift开发混编教程,代理的相互调用,block的实现。OC调用Swift中的代理, OC调用Swift中的Block 闭包,swift 3.0
- 根据参数动态加载bean(一个接口多个实现的调用方法)
- java动态代理中的invoke方法是如何被自动调用的
- c# 动态加载dll文件,并实现调用其中的简单方法
- c# 动态加载dll文件,并实现调用其中的方法(推荐)
- Java动态代理的两种实现方法
- Java动态代理的两种实现方法
- JAVAWEB开发之Servlet3.0新特性的使用以及注解的详细使用和自定义注解的方法、动态代理的使用、利用动态代理实现细粒度的权限控制以及类加载和泛型反射