此篇教程讲述通过runtime扩展NSObject,可以直接用字典给Model赋值,这是相当有用的技术呢。
iOS 中可以通过 NSPredicate 来处理正则表达式。相关资料如下:
NSPredicate 苹果官方文档:
http://developer.apple.com/documentation/Cocoa/Conceptual/Predicates/predicates.html
Predicate format strings:
http://developer.apple.com/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html
ICU 正则表达式规则:
http://www.icu-project.org/userguide/regexp.html
关于runtime的详情以后会详细介绍
源码:
NSObject+Property.h 与 NSObject+Property.m
// // NSObject+Property.h // ModelValueTest1.0 // // Created by Lisa on 14-9-15. // Copyright (c) 2014年 Lisa. All rights reserved. // #import <Foundation/Foundation.h> @interface NSObject (Property) -(void)setDataDictionary:(NSDictionary *)dataDictionary; -(NSDictionary*)dataDictionary; @end
// // NSObject+Property.m // ModelValueTest1.0 // // Created by Lisa on 14-9-15. // Copyright (c) 2014年 Lisa. All rights reserved. // #import "NSObject+Property.h" #import <objc/runtime.h> @implementation NSObject (Property) #pragma mark--Public method -(void)setDataDictionary:(NSDictionary *)dataDictionary { [self setAttributes:dataDictionary obj:self]; } -(NSDictionary*)dataDictionary { //获取属性列表 NSArray *properties = [self propertyNames:[self class]]; //根据属性列表获取属性值 return [self propertiesAndValuesDictionary:self properties:properties]; } #pragma mark--- Private method //通过属性名字拼凑 setter 方法 -(SEL)getSetterSelWithAttibuteName:(NSString *)attributeName { NSString *captial = [[attributeName substringToIndex:1]uppercaseString]; NSString *setterSelStr = [NSString stringWithFormat:@"set%@%@:",captial,[attributeName substringFromIndex:1]]; return NSSelectorFromString(setterSelStr); } //通过字典设置属性 -(void)setAttributes:(NSDictionary *)dataDic obj:(id)obj { //获取所有的key值 NSEnumerator *keyEnum = [dataDic keyEnumerator]; //字典的key值(与model的属性值一一对应) id attrbuteName = nil; while (attrbuteName = [keyEnum nextObject]) { //获取 拼凑的setter方法 SEL sel = [obj getSetterSelWithAttibuteName:attrbuteName]; //验证setter方法是否能回应 if ([obj respondsToSelector:sel]) { id value = nil; id tmpValue = dataDic[attrbuteName]; if ([tmpValue isKindOfClass:[NSNull class]]) { //如果是NSNull 类型,则 value值为空 value = nil; } else { value = tmpValue; } //执行setter 方法 [obj performSelectorOnMainThread:sel withObject:value waitUntilDone:[NSThread isMainThread]]; } } } //获取一个类的属性名字列表 -(NSArray *)propertyNames:(Class)class { NSMutableArray *propertyNames = [[NSMutableArray alloc]init]; unsigned int propertyCount = 0; objc_property_t *properties = class_copyPropertyList(class, &propertyCount); for (unsigned int i =0; i<propertyCount; ++i) { objc_property_t property = properties[i]; const char *name = property_getName(property); [propertyNames addObject:[NSString stringWithUTF8String:name]]; } free(properties); return propertyNames; } //根据属性数组获取该属性的值 -(NSDictionary*)propertiesAndValuesDictionary:(id)obj properties:(NSArray *)properties { NSMutableDictionary *propertiesValueDic = [NSMutableDictionary dictionary]; for (NSString *property in properties) { SEL getSel =NSSelectorFromString(property); if ([obj respondsToSelector:getSel]) { NSMethodSignature *signature = nil; signature = [obj methodSignatureForSelector:getSel]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; [invocation setTarget:obj]; [invocation setSelector:getSel]; NSObject *__unsafe_unretained valueObj = nil; [invocation invoke]; [invocation getReturnValue:&valueObj]; //assign to @"" string if (valueObj == nil) { valueObj = @""; } propertiesValueDic[property] = valueObj; } } return propertiesValueDic; } @end
测试的model
LModelItems.h与LModelItems.m
// // LModelItems.h // ModelValueTest1.0 // // Created by Lisa on 14-9-15. // Copyright (c) 2014年 Lisa. All rights reserved. // #import <Foundation/Foundation.h> @interface LModelItems : NSObject @property(nonatomic,strong)NSString *name; @property(nonatomic,strong)NSNumber *age; @property(nonatomic,strong)NSDictionary *addressDic; @property(nonatomic,strong)NSArray *eventd; @end
// // LModelItems.m // ModelValueTest1.0 // // Created by Lisa on 14-9-15. // Copyright (c) 2014年 Lisa. All rights reserved. // #import "LModelItems.h" @implementation LModelItems @end
使用的场景:
在控制器中 >>>>>LViewController.h与LViewController.m
// LViewController.h // ModelValueTest1.0 // // Created by Lisa on 14-9-15. // Copyright (c) 2014年 Lisa. All rights reserved. // #import <UIKit/UIKit.h> @interface LViewController : UIViewController @end
// // LViewController.m // ModelValueTest1.0 // // Created by itotem on 14-9-15. // Copyright (c) 2014年 Lisa. All rights reserved. // #import "LViewController.h" #import "NSObject+Property.h" #import "LModelItems.h" @interface LViewController () @end @implementation LViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; LModelItems *model = [LModelItems new]; //通过字典赋值 model.dataDictionary = @{@"name":@"Lisa",@"age":@26,@"addressDic":@{@"provinces":@"北京",@"area":@"海淀区"},@"eventd":@[@"first",@"second",@"third"]}; //打印赋值结果 NSLog(@"%@",model.dataDictionary); NSLog(@"name=%@",model.name); NSLog(@"age=%@",model.age); NSLog(@"addressDic=%@",[model.addressDic objectForKey:@"provinces"]); NSLog(@"eventd=%@",model.eventd); } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
打印信息:
2014-09-15 17:11:36.948 ModelValueTest1.0[8386:60b] {
addressDic = {
area = "\U6d77\U6dc0\U533a";
provinces = "\U5317\U4eac";
};
age = 26;
eventd = (
first,
second,
third
);
name = Lisa;
}
2014-09-15 17:11:36.950 ModelValueTest1.0[8386:60b] name=Lisa
2014-09-15 17:11:36.951 ModelValueTest1.0[8386:60b] age=26
2014-09-15 17:11:36.952 ModelValueTest1.0[8386:60b] addressDic=北京
2014-09-15 17:11:36.952 ModelValueTest1.0[8386:60b] eventd=(
first,
second,
third
)
以下是两段核心代码(符合单一职能):