NSDictionary stringForKey:并将[NSNull null]强制转换为NSString*

Ste*_*eve 6 iphone objective-c

我最近告诉铸造[NSNull null](NSString*)是"可怕的".

但是,如果键不在字典中,-[NSDictionary stringForKey:]方法将返回[NSNull null],如果我不进行转换,编译器会对我大喊大叫.

我错过了什么吗?

编辑:

我的错误......我想我可能会开始看到这个问题......

正如大家所指出的那样,在NSDictionary上没有stringForKey:方法,是的,当我问这个问题时我正在考虑用户默认值...所以我回去看看我在做什么......这里是:

NSString * someValue = (NSString*)[myDictionary objectForKey:@"key"];
if (someValue == (NSString*)[NSNull null]) ...
Run Code Online (Sandbox Code Playgroud)

如果在这种情况下我不做演员,我会收到以下错误:

warning: comparison of distinct Objective-C types 'struct NSNull *' and 'struct NSString *' lacks a cast
Run Code Online (Sandbox Code Playgroud)

铸造价值"解决"了问题,我宁愿不写10行,其中一个会做...

这不好吗?我会在哪里遇到问题?

也:

字典来自JSON库...在这种情况下,NULL是有效值,所以也许并不是NSDictionary在缺少密钥时返回它们,而是键实际上是键,并且值是实际上是null.

Jon*_*pan 14

NSDictionary不会返回实例,NSNull除非您或其他来源将它们放在那里.同样,NSDictionary也没有回应-stringForKey:.你也许在考虑NSUserDefaults

如果你有一个实例,NSDictionary你要做的只是从中获取一个字符串,你可以尝试类似下面的代码.

NSString *MyGetString(NSDictionary *dict, id key, NSString *fallback) {
    id result = [dict objectForKey: key];

    if (!result)
        result = fallback;
    else if (![result isKindOfClass: [NSString class]])
        result = [result description];

    return result;
}
Run Code Online (Sandbox Code Playgroud)

传递一个后备字符串fallback- 如果没有对象与该键相关联,该函数将使用该字符串key.

  • 如果你的意思是将"NSNull"转换为"NSString",那就太可怕了,因为它就像把狗叫做鱼一样.是的,它们都在同一层次结构中('NSObject`的子类与*Chordata*中的物种相比)但它们是非常不同的东西.---如果你的意思是*比较*两个不同类型的对象(如你更新的问题),你可以将两者都转换为`id`,它们都是(所以这是一个安全的比较.)例如`(id) someValue ==(id)[NSNull null]`有效.更好的方法是将字典存储在`id`开头,并且只在*检查类型后才转换为`NSString`*. (3认同)

moh*_*enr 7

正如Jonathan的代码所示,如​​果你使用isKindOfClass:方法会更好.即使您更改了检索对象的方法等,它也会保护您,并且是更准确的检查.

还要记住,只有在不是AND 时才[someValue isKindOfClass:[NSString class]]返回它是一个意味着它也足以测试值.YESsomeValuenilNSStringnil


wal*_*lky 6

演员是"坏",因为NSNull 没有一个NSString.转换不会改变指向的对象的实际类型,它只会改变编译器,嗯,对它的态度.

在所示的非常特殊的情况下,您要对对象进行的唯一事情是对指针相等性的直接测试,您的方法将起作用,但它是潜在的未来错误的来源.这种使编译器警告静音的hacky使得人们不耐烦,如果有更好的方法,应该避免.

当然,真正的问题是之前的演员阵容,其中NSObject*from objectForKey:直接演员阵容NSString*,没有问题.目前你可以逃脱它因为你认为你只能获得字符串NSNull,但是如果JSON库发生变化或者没有兑现合同会发生什么?做你喜欢的事情真的会更好:

NSObject* someValue = [myDictionary objectForKey:@"key"];
NSString* someStr = nil;
if (someValue == [NSNull null])
   ...
else if ([someValue isKindOfClass:[NSString class]])
   someStr = (NSString*) someValue;
....
Run Code Online (Sandbox Code Playgroud)