2015-01-15 98 views
1

我需要根据从远程服务器通过JSON提供的NSDictionary设置一堆对象属性。我不想覆盖不在字典中的属性。使用与属性名称不同的键从NSDictionary设置对象的属性

因为有很多的属性,我早就一系列语句看起来像这样:

if (dictionary[@"address_1"] != [NSNull null]) 
    self.configuration.userAddress1 = dictionary[@"address_1"]; 

在字典中的键是不相同的属性的名称;有两种不同的系统是分开成长的,我试图一起工作。

也许我一直在做太多的Ruby编码,但它似乎应该有一个更好的Objective-C成语这样做。有任何想法吗?

+0

我应该提到属性名称和字典键名不完全相同:例如userAddress1 vs address_1。那是因为他们是分开成长的两个不同的系统,试图一起工作。所以我在这个过程中做了一些“翻译”。 – John

+0

这是一个非常重要的观点,因为如果它不是真的,这将如[使用'setValuesForKeysWithDictionary:'](http://stackoverflow.com/questions/6299007/dynamically-populate-object-properties-with -dictionary值/ 6299057#6299057)。但是,如果您转换字典键_first_,您仍然可以使用它。 –

+0

H'mm。现在这是一个想法。 – John

回答

1

不,它不是红宝石,因为Objective-C是动态输入的。你可以用键值编码来做到这一点:

for (NSString *key in dictionary) 
{ 
    id value = dictionary[key]; 
    [self.configuration setValue:value forKey:key]; 
} 

但看到我的意见here

顺便说一句:如果一个密钥不存在于字典中,结果是nil而不是[NSNull null]

因此,如果您不想设置不在字典中的属性,则不得不另外执行任何操作。如果您不想设置值为[NSNull null]的字典中的属性,则仍可以添加该检查。

如果你不希望设置空的:

for (NSString *key in dictionary) 
{ 
    id value = dictionary[key]; 
    if (value != [NSNull null]) 
    { 
    [self.configuration setValue:value forKey:key]; 
    } 
} 

如果你想设置为空值与零:

for (NSString *key in dictionary) 
{ 
    id value = dictionary[key]; 
    if (value == [NSNull null]) 
    { 
    value = nil; 
    } 
    [self.configuration setValue:value forKey:key]; 
} 
+1

但是,从JSON解析创建的字典包含'NSNull'值并不罕见。看来OP想要检查'NSNull'值并采取相应的行动。 – rmaddy

+0

不,这并不罕见,但他说:“我不想覆盖不在字典中的属性。”他没有说:“我不想在字典中覆盖'null'的属性。” (可能的话,如果在字典中有一个键值为'[NSNull null]'的键你想把属性设置为'nil')。但是我添加了一个说明。 –

+0

是的,我测试[NSNull null]的原因是因为字典确实包含那种类型的null。测试无效不起作用。另一个复杂因素是字典和属性名称中的键名不完全相同(由于历史原因)。 – John

1

一个在Objective-C可能成语是:不要” t有很多对象属性。有一个属性,一个字典!现在,基于传入字典填充该字典很容易。

3

听起来像是你想要一个简单的映射解决方案 - 你可以手卷一个这样

[@{ 
    @"address_1" : @"address1", 
    @"address_2" : @"address2", 
    ... 
    } enumerateKeysAndObjectsUsingBlock:^(NSString *remoteKey, NSString *localKey, BOOL *stop) { 
    id remoteValue = dictionary[remoteKey]; 

    if (![remoteValue isEqual:NSNull.null]) { 
     [self.configuration setValue:remoteValue forKey:localKey]; 
    } 
    }]; 

这适用于一些基本Null检查逻辑,并允许远程/本地对象有不同的属性名称

+0

我投票赞成这是因为这是一个很酷的想法,要记住未来。谢谢! – John

0

另一种方法是在课程中覆盖-setValue:forUndefinedKey:并在那里映射密钥。

- (void) setValue:(id)value forUndefinedKey:(NSString*)key 
{ 
    static dispatch_once_t once; 
    static NSDictionary* map; 
    dispatch_once(&once, ^{ 
     map = @{ 
       @"address_1" : @"address1", 
       @"address_2" : @"address2", 
       // ... 
       }; 
    }); 

    NSString* newKey = map[key]; 
    if (newKey) 
     [self setValue:value forKey:newKey]; 
    else 
     [super setValue:value forUndefinedKey:key]; 
} 

现在您可以使用-setValuesForKeysWithDictionary:与原始字典。该方法将替代nil作为NSNull对象,因此您必须决定这是否是您想要的。

如果需要,您也可以通过覆盖-valueForUndefinedKey:去其他方向。

相关问题