iOS NSDictionary跟Model

iOS NSDictionary和Model

此篇教程讲述通过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

)

 

以下是两段核心代码(符合单一职能):

iOS NSDictionary跟Model

iOS NSDictionary跟Model