objectForKey stringValue 使我的应用程序崩溃?
我有一个类,用于在数组中设置对象。在这个类中,我有一个自定义的“initWithDictionary”,我在其中解析 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 或包含有效字符串,它都不起作用。仅当我执行以下操作(并且字符串不为空)时:
self.bookTitle = [parsedDictionary objectForKey:@"book_title"];
在这种情况下 stringValue
不正确吗?如果是这样,我如何正确使用它来设置正确的 NSNull 替换?
谢谢
I have a class that I use to setup objects in an array. In this class I have a custom "initWithDictionary", where I parse a JSON
dictionary. However, as I am running into NSNull
, this crashes my app. To get around this, I set up a class that handles exceptions, so when a string is NSNull
, it's replace it with @""
. or -1 for integers.
This is my NullExtensions class:
@interface NSNull (valueExtensions)
-(int)intValue;
-(NSString *)stringValue;
@end
@implementation NSNull (valueExtensions)
-(int)intValue {
return -1;
}
-(NSString*)stringValue {
return @"";
}
@end
However, in my initWithDictionary method, the following code crashes my app:
self.bookTitle = [[parsedDictionary objectForKey:@"book_title"] stringValue];
It doesn't work regardless of the object in the parsed dictionary being NSNull
or containing a valid string. Only if I do the following (and the string is not null):
self.bookTitle = [parsedDictionary objectForKey:@"book_title"];
Is stringValue
incorrect in this case? And if so, how do I use it properly in order to setup proper NSNull
replacements?
Thx
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您真的真的不想向 NSNull 添加一个类别来添加此类常见方法。这将改变应用程序中所有实例的 NSNull 行为,包括由底层框架创建的仅供其私人使用的实例。
如果您需要一个表示“值不存在,因此我将返回这些默认值”概念的值类,请创建一个准确表示该概念的类或实例。
至于为什么会崩溃,在没有看到崩溃的实际细节之前我无法告诉你。
而且,是的,向添加这样一个通用方法的类添加一个类别确实太很糟糕。所需要的只是插件或框架中的一小段代码,它可以执行以下操作:
并非非常牵强 - 由于完全这种随意添加类别,我不得不调试令人讨厌的崩溃程序或不当行为。
如果您要通过类别向类添加方法,请为方法名称添加前缀,以便将它们与现有功能隔离。它仍然很脆弱,但可以控制。
You really really don't want to add a category to NSNull that adds such common methods. That will change the behavior of NSNull for all instances in the application, including ones created by the underlying frameworks solely for their private use.
If you need a value class that represents the notion of "value doesn't exist and therefore I'm going to return these default values instead", create a class or instance that represents exactly that.
As for why it crashes, I couldn't tell you without seeing the actual details of the crash.
And, yes, it really is THAT bad to add a category to a class that adds such a common method. All it takes is one bit of code in a plug-in or framework that does:
Not terribly farfetched -- I have had to debug nasty crashers or misbehaviors due to exactly this kind of willy-nilly category addition.
If you are going to add methods to a class via categories, prefix your method names so as to isolate them from existing functionality. It is still fragile, but manageably so.
您不必在
NSNull
上创建类别,为此您还必须向NSString
添加类似的类别(这就是它崩溃的原因,因为真正的字符串不响应 stringValue) -相反,尝试在NSDictionary
上创建一个帮助器类别,例如“stringForKey
”,它使用 Johan 发布的代码并返回NSString
,可能还应该强制执行所有其他类型也被映射到空字符串。Instead of creating categories on
NSNull
, for which you would also have to add a similar category toNSString
(that's why it crashes, because real strings do not respond to stringValue) - instead try creating a helper category onNSDictionary
like "stringForKey
" that uses the code Johan posted and returns anNSString
, probably also should enforce all other types get mapped to empty strings as well.您编写的 NSNull 扩展对我来说看起来不错,但使用像 stringValue 这样的方法可能会令人困惑,因为像 NSNumber 这样的其他类使用它。
但就我个人而言,我认为在这种情况下 NSNull 替换是不必要的。如果您刚刚进行了快速测试,您可以在需要的地方替换 NSNull。例如
The NSNull extensions you have written look ok to me but using a method like stringValue may be confusing since other classes like NSNumber use this.
Personally though, I think NSNull replacement in this instance is unnecessary. If you just made a quick test you can replace the NSNull where you need to. e.g.
您正在向
NSString
询问其stringValue
。无需将字符串转换为字符串。试试这个:
编辑:您不应该在您创建的
NSNull
上使用该类别。你不需要它,也不应该想要它。如果字典的源插入NSNull
实例,请继续使用我上面的代码。通常您会期望简单地没有为键插入任何值,此时您可以简单地查看[parsedDictionary objectForKey:@"book_title"]
是否返回任何内容。You are asking an
NSString
for itsstringValue
. No need to convert a string to a string.Try this:
Edit: You should not use the category on
NSNull
you created. You don't need it, nor should you want it. If the source for the dictionary insertsNSNull
instances, go ahead and use my code above. Normally you would expect to simple have no value inserted for the key, at which time you can simple see if[parsedDictionary objectForKey:@"book_title"]
returns anything.您确定字典返回
[NSNull null]
吗?默认情况下,当未找到某个键的值时,字典将返回nil
,而不是[NSNull null]
。Are you sure that the dictionary is returning
[NSNull null]
? By default, dictionaries returnnil
, not[NSNull null]
, when an value isn't found for a key.这是有道理的,因为
stringValue
不是NSString
上的有效方法。它适用于NSValue
及其子类,但不适用于NSString
。That makes sense, since
stringValue
is not a valid method onNSString
. It will work forNSValue
and its subclasses, but notNSString
.