objectForKey stringValue 使我的应用程序崩溃?

发布于 2024-08-13 00:12:54 字数 887 浏览 4 评论 0原文

我有一个类,用于在数组中设置对象。在这个类中,我有一个自定义的“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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

难得心□动 2024-08-20 00:12:54

您真的真的不想向 NSNull 添加一个类别来添加此类常见方法。这将改变应用程序中所有实例的 NSNull 行为,包括由底层框架创建的仅供其私人使用的实例。

如果您需要一个表示“值不存在,因此我将返回这些默认值”概念的值类,请创建一个准确表示该概念的类或实例。

至于为什么会崩溃,在没有看到崩溃的实际细节之前我无法告诉你。


而且,是的,向添加这样一个通用方法的类添加一个类别确实很糟糕。所需要的只是插件或框架中的一小段代码,它可以执行以下操作:

if ([fooMaybeNull respondsToSelector: @selector(intValue)] bar = [fooMaybeNull intValue];

并非非常牵强 - 由于完全这种随意添加类别,我不得不调试令人讨厌的崩溃程序或不当行为。

如果您要通过类别向类添加方法,请为方法名称添加前缀,以便将它们与现有功能隔离。它仍然很脆弱,但可以控制。

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:

if ([fooMaybeNull respondsToSelector: @selector(intValue)] bar = [fooMaybeNull intValue];

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.

遗心遗梦遗幸福 2024-08-20 00:12:54

您不必在 NSNull 上创建类别,为此您还必须向 NSString 添加类似的类别(这就是它崩溃的原因,因为真正的字符串不响应 stringValue) -相反,尝试在 NSDictionary 上创建一个帮助器类别,例如“stringForKey”,它使用 Johan 发布的代码并返回 NSString,可能还应该强制执行所有其他类型也被映射到空字符串。

Instead of creating categories on NSNull, for which you would also have to add a similar category to NSString (that's why it crashes, because real strings do not respond to stringValue) - instead try creating a helper category on NSDictionary like "stringForKey" that uses the code Johan posted and returns an NSString, probably also should enforce all other types get mapped to empty strings as well.

¢好甜 2024-08-20 00:12:54

您编写的 NSNull 扩展对我来说看起来不错,但使用像 stringValue 这样的方法可能会令人困惑,因为像 NSNumber 这样的其他类使用它。

但就我个人而言,我认为在这种情况下 NSNull 替换是不必要的。如果您刚刚进行了快速测试,您可以在需要的地方替换 NSNull。例如

id testObject = [parsedDictionary objectForKey:@"book_title"];
self.bookTitle = testObject==[NSNull null] ? @"" : testObject;

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.

id testObject = [parsedDictionary objectForKey:@"book_title"];
self.bookTitle = testObject==[NSNull null] ? @"" : testObject;
洒一地阳光 2024-08-20 00:12:54

您正在向 NSString 询问其 stringValue。无需将字符串转换为字符串。

试试这个:

if (![[parsedDictionary objectForKey:@"book_title"] isKindOfClass:[NSNull class]]) {
    self.bookTitle = [parsedDictionary objectForKey:@"book_title"];
} else {
    self.bookTitle = @"";
}

编辑:您不应该在您创建的NSNull 上使用该类别。你不需要它,也不应该想要它。如果字典的源插入 NSNull 实例,请继续使用我上面的代码。通常您会期望简单地没有为键插入任何值,此时您可以简单地查看 [parsedDictionary objectForKey:@"book_title"] 是否返回任何内容。

You are asking an NSString for its stringValue. No need to convert a string to a string.

Try this:

if (![[parsedDictionary objectForKey:@"book_title"] isKindOfClass:[NSNull class]]) {
    self.bookTitle = [parsedDictionary objectForKey:@"book_title"];
} else {
    self.bookTitle = @"";
}

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 inserts NSNull 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.

日久见人心 2024-08-20 00:12:54

您确定字典返回 [NSNull null] 吗?默认情况下,当未找到某个键​​的值时,字典将返回 nil,而不是 [NSNull null]

Are you sure that the dictionary is returning [NSNull null]? By default, dictionaries return nil, not [NSNull null], when an value isn't found for a key.

太阳哥哥 2024-08-20 00:12:54

但是,在我的 initWithDictionary 方法中,以下代码使我的应用程序崩溃:

self.bookTitle = [[parsedDictionary objectForKey:@"book_title"] stringValue];

无论解析字典中的对象是 NSNull 还是包含有效字符串,它都不起作用。

这是有道理的,因为 stringValue 不是 NSString 上的有效方法。它适用于 NSValue 及其子类,但不适用于 NSString

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.

That makes sense, since stringValue is not a valid method on NSString. It will work for NSValue and its subclasses, but not NSString.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文