NSDirectory与NSObject自动转换

来源:互联网 发布:java log4j 教程 编辑:程序博客网 时间:2024/06/11 19:09
NSDirectory-->NSObject
[object setValuesForKeysWithDictionary:properties]NSObject--> NSDirectoryNSDictionary *properties = [anObject dictionaryWithValuesForKeys:[anObject allKeys]];


注:
1、NSDirectory-->NSObject
可以封装一下(或者可以直接扩展到NSObject中):
// In your custom class + (id)customClassWithProperties:(NSDictionary *)properties {   return [[[self alloc] initWithProperties:properties] autorelease];} - (id)initWithProperties:(NSDictionary *)properties {   if (self = [self init])      {      [self setValuesForKeysWithDictionary:properties];      }    return self; }
2、NSObjct--> NSDirectory
There is no allKeys on NSObject. You'll need to create an extra category on NSObject like below:NSObject+PropertyArray.h
   @interface NSObject (PropertyArray)     - (NSArray *) allKeys;   @end
NSObject+PropertyArray.m
#import @implementation NSObject (PropertyArray)- (NSArray *) allKeys {    Class clazz = [self class];    u_int count;    objc_property_t* properties = class_copyPropertyList(clazz, &count);    NSMutableArray* propertyArray = [NSMutableArray arrayWithCapacity:count];    for (int i = 0; i < count ; i++) {        const char* propertyName = property_getName(properties[i]);
<span style="font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu sans Mono', 'Bitstream Vera sans Mono', 'Courier new', monospace, serif;">        [propertyArray addObject:[NSString  stringWithCString:propertyName encoding:NSUTF8StringEncoding]];</span>
    }    free(properties);    return [NSArray arrayWithArray:propertyArray];
}@end
Example:
#import "NSObject+PropertyArray.h"...MyObject *obj = [[MyObject alloc] init];obj.a = @"Hello A";  //setting some values to attributesobj.b = @"Hello B";//dictionaryWithValuesForKeys requires keys in NSArray. You can now//construct such NSArray using `allKeys` from NSObject(PropertyArray) category
NSDictionary *objDict = [obj dictionaryWithValuesForKeys:[obj allKeys]];
//Resurrect MyObject from NSDictionary using setValuesForKeysWithDictionaryMyObject *objResur = [[MyObject alloc] init];[objResur setValuesForKeysWithDictionary:objDict];
另外一种做法:
 Assuming that your class conforms to the Key-Value Coding protocol, you could use the following: (defined as a category on NSDictionary for convenience): 
 // myNSDictionaryCategory.h:      @interface NSDictionary (myCategory)      - (void)mapPropertiesToObject:(id)instance      @end 
     // myNSDictionaryCategory.m:     - (void)mapPropertiesToObject:(id)instance     { 
        for (NSString * propertyKey in [self allKeys])         { 
            [instance setValue:[self objectForKey:propertyKey]                         forKey:propertyKey];         }     } 
//And here's how you would use it:      #import "myNSDictionaryCategory.h" 
     //...      [someDictionary mapPropertiesToObject:someObject];
地址:http://stackoverflow.com/questions/830673/instantiating-custom-class-from-nsdictionary
注:如果NSDirctory包含的key-value里面的部分key在对象OBJECT中没有对应的属性的话,默认会抛出异常,原因:
对于未定义的key系统会调用setValue:forUndefinedKey,而setValue:forUndefinedKey的官方描述为:

setValue:forUndefinedKey:

Invoked by setValue:forKey: when it finds no property for a given key.
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
Parameters
value

The valuefor the key identified by key.

key

A stringthat is not equal to the name of any of the receiver'sproperties.

Discussion

Subclasses canoverride this method to handle the request in some other way. Thedefault implementation raises an NSUndefinedKeyException.

所以解决方案是重写setValue:forUndefinedKey方法即可(建议在NSObject的category中重写)

2、上述的转换(NSDirectory-->NSObject)只能自动赋值当前类的属性,无法自动赋值父类的属性。解决方法:在allkey方法中将父类的属性添加进去:如:

- (NSArray *) allKeys{    Class clazz = [self class];    u_int count;        objc_property_t* properties = class_copyPropertyList(clazz,&count);//    NSMutableArray*propertyArray = [NSMutableArray arrayWithCapacity:count];   NSMutableArray* propertyArray = [NSMutableArrayarray];    for (int i = 0; i < count ; i++) {       constchar* propertyName =property_getName(properties[i]);       [propertyArrayaddObject:[NSString stringWithCString:propertyNameencoding:NSUTF8StringEncoding]];    }    free(properties);        Class superClass = class_getSuperclass([self class]);    if (superClass != [NSObject class]) {       properties = class_copyPropertyList(superClass,&count);       for(int i = 0; i < count ; i++) {          const char* propertyName = property_getName(properties[i]);          [propertyArray addObject:[NSString stringWithCString:propertyNameencoding:NSUTF8StringEncoding]];       }    }        return [NSArray arrayWithArray:propertyArray];}


3、

另一个可供参考的示例:https://gist.github.com/mbogh/2585734(没有使用setValuesForKeysWithDictionary,自己进行了赋值,不建议这样处理

0 0
原创粉丝点击