代码之家  ›  专栏  ›  技术社区  ›  runmad

Objectforkey StringValue崩溃了我的应用程序?

  •  2
  • runmad  · 技术社区  · 16 年前

    我有一个用于在数组中设置对象的类。在这个类中,我有一个自定义的“initWithDictionary”,在这里我分析 JSON 字典。然而,当我遇到 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];
    

    不管解析字典中的对象 恩努尔 或包含有效字符串。仅当我执行以下操作时(字符串不为空):

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

    是 stringValue 这种情况下不正确?如果是这样,我如何正确使用它来设置正确的 恩努尔 替代品?

    谢谢

    6 回复  |  直到 16 年前
        1
  •  4
  •   Kendall Helmstetter Gelner    16 年前

    而不是在上创建类别 NSNull ,您还必须为其添加类似的类别 NSString (这就是它崩溃的原因,因为真正的字符串不响应StringValue)-而是尝试在 NSDictionary “就像” stringForKey “使用Johan发布的代码并返回 非字符串 ,可能还应该强制所有其他类型也映射到空字符串。

        2
  •  5
  •   bbum    16 年前

    你真的 真正地 不希望向nsnull中添加添加此类常用方法的类别。这将更改nsnull的行为 全部的 应用程序中的实例,包括由基础框架创建的仅供私人使用的实例。

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

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


    是的,真的 是 那 向添加此类公共方法的类中添加类别是错误的。它所需要的只是插件或框架中的一位代码,它可以:

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

    不是很牵强——我不得不调试一些令人讨厌的崩溃者或者由于 确切地 这种任意的类加法。

    如果要通过类别向类中添加方法, 给方法名加前缀,以便将它们与现有功能隔离开来。 . 它仍然脆弱,但可以管理。

        3
  •  3
  •   imnk    16 年前

    您编写的nsnull扩展在我看来是正常的,但使用类似StringValue的方法可能会令人困惑,因为其他类(如nsnumber)都使用这种方法。

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

    id testObject = [parsedDictionary objectForKey:@"book_title"];
    self.bookTitle = testObject==[NSNull null] ? @"" : testObject;
    
        4
  •  3
  •   Johan Kool    16 年前

    你在问一个 NSString 为其 stringValue . 不需要将字符串转换为字符串。

    试试这个:

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

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

        5
  •  0
  •   Dave DeLong    16 年前

    你确定字典会回来吗 [NSNull null] ?默认情况下,字典返回 nil 不是 [ nSnur-null ] ,当找不到键的值时。

        6
  •  0
  •   James Eichele Bernard Igiri    16 年前

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

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

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

    这是有道理的,因为 stringValue 不是上的有效方法 NSString . 它会起作用的 NSValue 及其子类,但不是 非字符串 .