Iphone objectForKey stringValue使我的应用程序崩溃?
我有一个类,用于在数组中设置对象。在这个类中,我有一个自定义的“initWithDictionary”,在这里我解析一个Iphone objectForKey stringValue使我的应用程序崩溃?,iphone,objective-c,null,nsstring,Iphone,Objective C,Null,Nsstring,我有一个类,用于在数组中设置对象。在这个类中,我有一个自定义的“initWithDictionary”,在这里我解析一个JSON字典。但是,由于我遇到了NSNull,这会使我的应用程序崩溃。为了解决这个问题,我设置了一个处理异常的类,因此当字符串为NSNull时,它将替换为@“。或-1表示整数 这是我的NullExtensions类: @interface NSNull (valueExtensions) -(int)intValue; -(NSString *)stringValue; @
JSON
字典。但是,由于我遇到了NSNull
,这会使我的应用程序崩溃。为了解决这个问题,我设置了一个处理异常的类,因此当字符串为NSNull
时,它将替换为@“
。或-1表示整数
这是我的NullExtensions类:
@interface NSNull (valueExtensions)
-(int)intValue;
-(NSString *)stringValue;
@end
@implementation NSNull (valueExtensions)
-(int)intValue {
return -1;
}
-(NSString*)stringValue {
return @"";
}
@end
但是,在我的initWithDictionary方法中,以下代码使我的应用程序崩溃:
self.bookTitle = [[parsedDictionary objectForKey:@"book_title"] stringValue];
无论解析字典中的对象是NSNull
还是包含有效字符串,它都不起作用。仅当我执行以下操作时(且字符串不为null):
在这种情况下,stringValue
是否不正确?如果是这样,我如何正确使用它来设置正确的NSNull
替换
Thx您正在请求一个
NSString
获取它的stringValue
。不需要将字符串转换为字符串
试试这个:
if (![[parsedDictionary objectForKey:@"book_title"] isKindOfClass:[NSNull class]]) {
self.bookTitle = [parsedDictionary objectForKey:@"book_title"];
} else {
self.bookTitle = @"";
}
编辑:您不应使用您创建的
NSNull
上的类别。你不需要它,也不应该想要它。如果字典的源代码插入了NSNull
实例,请继续使用上面的“我的代码”。通常,您希望simple没有为键插入任何值,这时您可以简单地查看[parsedDictionary objectForKey:@“book_title”]
是否返回任何内容。您编写的NSNull扩展在我看来是可以的,但使用类似stringValue的方法可能会让人困惑,因为其他类(如NSNumber)也会使用它
但我个人认为,在这种情况下,NSNull替换是不必要的。如果您只是做了一个快速测试,您可以在需要的地方替换NSNull。e、 g
id testObject = [parsedDictionary objectForKey:@"book_title"];
self.bookTitle = testObject==[NSNull null] ? @"" : testObject;
您真的不想向NSNull添加添加此类常用方法的类别。这将改变应用程序中所有实例的NSNull行为,包括由底层框架创建的仅供其私人使用的实例
如果您需要一个值类来表示“值不存在,因此我将返回这些默认值”,请创建一个正好表示该值的类或实例
至于它为什么会崩溃,我不能告诉你没有看到崩溃的实际细节
而且,是的,在类中添加一个类别来添加这样一个通用的方法确实是不好的。只需插件或框架中的一位代码即可:
if ([fooMaybeNull respondsToSelector: @selector(intValue)] bar = [fooMaybeNull intValue];
不太牵强——我不得不调试讨厌的撞车者或不当行为,因为正是这种随意添加的类别
如果要通过类别将方法添加到类中,请在方法名称前加前缀,以便将它们与现有功能隔离开来。它仍然很脆弱,但可以管理。您确定字典正在返回
[NSNull null]
?默认情况下,当找不到键的值时,字典返回nil
,而不是[NSNull null]
。而不是在NSNull
上创建类别,对于这些类别,您还必须向NSString
添加类似的类别(这就是它崩溃的原因,因为真正的字符串不响应stringValue)-相反,尝试在NSDictionary
上创建一个助手类别,如“stringForKey
”,它使用Johan发布的代码并返回一个NSString
,可能还应该强制所有其他类型也映射到空字符串
但是,在我的initWithDictionary方法中,以下代码使我的应用程序崩溃:
self.bookTitle = [[parsedDictionary objectForKey:@"book_title"] stringValue];
无论解析字典中的对象是NSNull还是包含有效字符串,它都不起作用
这是有道理的,因为
stringValue
不是NSString
上的有效方法。它适用于NSValue
及其子类,但不适用于NSString
,这没有意义吗?self.bookTitle是objectForKey:@“book_title”。即使它是null,它仍然会得到值,当我尝试使用bookTitle字符串时,它会崩溃。啊,那是因为你在字典中插入了NSNull作为对象,而不是简单地忽略它。您可以更改if语句来检查对象是否属于NSNull类,然后选择正确的行为。是的,它是NSNull-JSON解析器将使用它来指示nil值,而不是空字符串(这是不同的).创建这样的类别并没有那么糟糕-它存在于所有其他类中并不重要,因为他们永远不会知道它是否存在,所以尝试调用它!此外,说他应该创建一个新类型是不实际的,因为这是由JSON库返回的-当NSNull非常适合它的工作时,修改库以添加一个全新的类型是不实际的。无论如何,这是对类别的滥用。NSNull在一般意义上没有“stringValue”或“intValue”的含义,因此它不应该有这样的方法。相反,处理此字典的类应该执行“obj==[NSNull null]”检查,而不是盲目地向类型不明确的对象发送消息。我不得不稍微不同意bbum。虽然我认为您需要明智地在Cocoa Touch类上使用类别,也就是说,我认为您永远不应该覆盖现有的方法,但我认为在现有类中添加新功能一点也不重要。我大量使用类别,从未遇到过问题。实际上,它就像运行时一样:它非常容易以如此大的灵活性打破事物,但负责任地使用它的功能有助于大大增强应用程序开发。@LucasTizma您对类别的使用几乎是可以维护的,但您还需要考虑分层成本。在将一些大规模的代码库从Cocoa移植到iOS时,Cocoa类上的类别是t
self.bookTitle = [[parsedDictionary objectForKey:@"book_title"] stringValue];