情景:服务端下发了字段,用来判断客户端是否安装了某一款应用
下发字段为:@“_isInstall_baidu”
写一个AppInstallInfo的类,里面可以进行判断是否安装了某应用
我期望使用AppInstallInfo._isInstall_baidu的方式进行获取,可以直接得到,但是AppInstallInfo这个类里面 并没有这个属性 这时候,就要用到OC的动态属性
AppInstallInfo *info = [[AppInstallInfo alloc] init];
Bool isInstall = [info _isInstall_baidu];
或者
Bool isInstall = [info valueForKey:@"_isInstall_baidu”]
或者
Bool isInstall = info._isInstall_baidu
有以上三种方式获取这个值
Bool isInstall = [info _isInstall_baidu];
的时候,就可以从- (void)forwardInvocation:(NSInvocation *)invocation这个方法里得到返回值,得到是否安装的信息了。
当我使用Bool isInstall = [info valueForKey:@"_isInstall_baidu”]
的时候,就可以从- (id)valueForUndefinedKey:(NSString *)key这个方法里得到返回值,得到是否安装的信息了。
目前直接使用Bool isInstall = info._isInstall_baidu是不合法的。Xcode会报错。
但是有一种情况 用谓词NSPredicate的时候 比方说
NSPredicate* ex = [NSPredicate predicateWithFormat:@"info._isInstall_baidu == 1"];
NSDictionary* dic = [NSDictionary dictionaryWithObjectsAndKeys:info,@"info", nil];
BOOL SS = [ex evaluateWithObject:dic];
这么用的时候,把info._isInstall_baidu当成字符串的时候 NSPredicate 会进行转换,换成valueForKey的形式,这样就可以用了。
这样,就实现了获取类的动态属性
下发字段为:@“_isInstall_baidu”
写一个AppInstallInfo的类,里面可以进行判断是否安装了某应用
我期望使用AppInstallInfo._isInstall_baidu的方式进行获取,可以直接得到,但是AppInstallInfo这个类里面 并没有这个属性 这时候,就要用到OC的动态属性
AppInstallInfo *info = [[AppInstallInfo alloc] init];
Bool isInstall = [info _isInstall_baidu];
或者
Bool isInstall = [info valueForKey:@"_isInstall_baidu”]
或者
Bool isInstall = info._isInstall_baidu
有以上三种方式获取这个值
#import "AppInstallInfo.h"
#import <objc/runtime.h>
@implementation AppInstallInfo
//当我用valueForKey的时候,如果没有这个key 会自动调用这个方法,然后就可以在这个方法里进行一些操作了
- (id)valueForUndefinedKey:(NSString *)key
{
if ([key rangeOfString:@"_isInstall_"].location == 0)
{
NSString* url = @"Baidu_Url";
BOOL is = [[UIApplication sharedApplication] canOpenURL: [NSURL URLWithString:url]];
NSNumber* ret = [NSNumber numberWithBool :is];
return ret;
}
return [super valueForUndefinedKey:key];
}
//当我掉一个没有声明和实现的方法的时候 比方说[info _isInstall_baidu](info里并没有声明和实现_isInstall_baidu这个方法)会自动调到这里,然后就可以在这两个方法里做一些操作了
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
return [NSMethodSignature signatureWithObjCTypes:"@@:"];
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
NSString *key = NSStringFromSelector([invocation selector]);
if ([key rangeOfString:@"_isInstall_"].location == 0)
{
NSString* url = @"Baidu_Url";
BOOL is = [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:url]];
NSNumber* ret = [NSNumber numberWithBool :is];
[invocation setReturnValue:&ret];
return;
}
else
{
return [super forwardInvocation:invocation];
}
}
这样 当我使用Bool isInstall = [info _isInstall_baidu];
的时候,就可以从- (void)forwardInvocation:(NSInvocation *)invocation这个方法里得到返回值,得到是否安装的信息了。
当我使用Bool isInstall = [info valueForKey:@"_isInstall_baidu”]
的时候,就可以从- (id)valueForUndefinedKey:(NSString *)key这个方法里得到返回值,得到是否安装的信息了。
目前直接使用Bool isInstall = info._isInstall_baidu是不合法的。Xcode会报错。
但是有一种情况 用谓词NSPredicate的时候 比方说
NSPredicate* ex = [NSPredicate predicateWithFormat:@"info._isInstall_baidu == 1"];
NSDictionary* dic = [NSDictionary dictionaryWithObjectsAndKeys:info,@"info", nil];
BOOL SS = [ex evaluateWithObject:dic];
这么用的时候,把info._isInstall_baidu当成字符串的时候 NSPredicate 会进行转换,换成valueForKey的形式,这样就可以用了。
这样,就实现了获取类的动态属性
如有问题可以发邮件到 friday_holiday@163.com进行讨论