我是否可以创建扩展- (id)valueForKey:(NSString *)key
方法的类别,如果此键的值相等[NSNull null]
,则会返回空字符串@""
。
它连接到我在JSON中从后端服务器获得的某些键的nil值。
因此,如果我需要为属性保存一些值,它可以是nil。
假设我使用此代码的值为key nil
artist.name = ad[@"artist"][@"name"]; // nil value on the right.
因此,如果我有扩展程序,则会检查密钥值并返回@""
nil
的意图。这是否有意义。
或者我是否需要扩展NSManagedObject
来检查属性类型,然后返回相应的值@""
,0
或nil
或0.0f
另一种不是字符串类型。
答案 0 :(得分:2)
您可以在NSDictionary
上定义一个类别,然后在那里进行转换,而不是在NSObject
上定义类别:
@interface NSObject (DBNullHandling)
-(NSString*)nullToEmpty;
@end
@implementation NSObject (DBNullHandling)
-(id)nullToEmpty {
return (self == [NSNull null]) ? @"" : self;
}
@end
现在你可以这样做:
artist.name = [ad[@"artist"][@"name"] nullToEmpty];
如果ad[@"artist"][@"name"]
返回[NSNull null]
,artist.name
会被分配@""
;否则,它将被赋予ad[@"artist"][@"name"]
返回的值。
答案 1 :(得分:1)
我建议您检查密钥是否存在,而不是将NSDictionary
子类化以更改valueForKey:
的实现。所以你会这样做:
BOOL keyExistsInDictionary = [[myDict allKeys] containsObject:key];
id objectForKey = [myDict objectForKey:key];
if (nil == objectForKey && keyExistsInDictionary) objectForKey = @"";
如果objectForKey:
返回nil,您可以检查keyExistsInDictionary
以查看密钥是否存在且只包含[NSNull null]
。这使您可以区分存在的密钥和不修改NSDictionary
的密钥。
答案 2 :(得分:1)
我所做的是在执行作业之前进行检查。三方运营商是一个很好的速记方式。你有:
artist.name = ad[@"artist"][@"name"];
相反,我会写
id val = ad[@"artist"][@"name"];
artist.name = val ? val : @""; // or val ?: @""
(我还没有完全理解这个问题,因此可能有必要将检查分解为更多阶段或以某种方式修改它以检查[NSNull null]
而不是nil。但是你明白了。)
答案 3 :(得分:1)
我可以创建将扩展的类别 - (id)valueForKey:(NSString *)key method
这里简短的回答是不,不要那样做。类别允许您通过添加方法扩展类,但不应使用它们来覆盖现有方法。这样做的主要原因是它不可靠 - 类别中的方法添加到类中的顺序没有定义,这意味着如果你有两个类别覆盖相同的方法,你就不知道哪个该类最终将最终得到的方法的版本。
另一个原因是您无法从覆盖方法引用原始方法,因此您必须重新实现要保留的行为。
最后,类别会更改类,因此该类的每个实例都将具有新行为。当您添加方法时,这通常不是问题 - 不使用新方法的代码不受新功能的影响。但是,当您更改现有方法时,尤其是对于NSDictionary
广泛使用的类时,您很可能会破坏大量现有代码。
如果此键的值相等[NSNull null],它将返回空字符串@“”
你已经得到了一些好的答案,但是既然你问过类别,这里有一种方法可以恰当地使用一个类别来解决问题。不要尝试更改-valueForKey:
,而是使用类别添加一个名为-stringForKey:
的新方法,该方法返回一个字符串。听起来你只是在使用字符串,所以这似乎是一个合理的解决方案。实现可以调用-valueForKey:
并将非字符串对象转换为字符串:
@interface NSDictionary (StringValue)
- (NSString *)stringForKey:(NSString*)key;
@end
@implementation NSDictionary (StringValue)
- (NSString *)stringForKey:(NSString*)key
{
id value = [self valueForKey:key];
NSString *string;
if ([value isKindOfClass:[NSString class]]) {
string = (NSString*)value;
}
else if ([value isKindOfClass:[NSNull class]]) {
string = @"";
}
else {
string = [value description];
}
return string;
}
@end