检查NSDictionary中是否存在密钥为null

时间:2011-08-11 19:28:31

标签: iphone objective-c nsstring nsdictionary

我确实搜索了如何检查NSDictionary密钥是否存在,并提出了解决方案。但它仍然会给我一个错误,即向键添加空值。 我不确定我的代码是否正确。如果有人对此有任何想法可以帮助我。

NSDictionary *result;
id myImageURL = [result objectForKey:@"url"];
if ((NSNull *)myImageURL == [NSNull null])
    myImageURL = @"";

id myImage = [result objectForKey:@"image"];
if ((NSNull *)myImage == [NSNull null])
    myImage = @"";

检查null是否添加任何内容,如果不添加该值。但它仍然给我一个错误,不知道为什么。

/****OUTPUT*****/

2011-08-11 14:56:06.668 Tab_Table_Win[6510:207] RESULTS : {
image = "<UIImage: 0xbc332c0>";
url = "http://a3.twimg.com/profile_images/999228511/normal.jpg";
}

2011-08-11 14:56:06.669 Tab_Table_Win[6510:207] url : http://a3.twimg.com/profile_images/999228511/normal.jpg
2011-08-11 14:56:06.670 Tab_Table_Win[6510:207] IMage : <UIImage: 0xbc332c0>

/*****Breaks Here ***/

2011-08-11 14:56:06.876 Tab_Table_Win[6510:207] RESULTS : {
}
2011-08-11 14:56:06.878 Tab_Table_Win[6510:207] url : (null)
2011-08-11 14:56:06.879 Tab_Table_Win[6510:207] IMage : (null)
2011-08-11 14:56:06.881 Tab_Table_Win[6510:207] *** Terminating app due to uncaught    exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary setObject:forKey:]: attempt to insert nil key'

13 个答案:

答案 0 :(得分:14)

正确答案是:

NSDictionary *result;
NSURL *myImageURL = [result objectForKey:@"url"];
UIImage *myImage = [result objectForKey:@"image"];

/**** Correct way ****/
if (myImageURL != nil && myImage != nil) {
    [images setObject:myImage forKey:myImageURL];
}

感谢您的所有解释。

答案 1 :(得分:14)

汤米完美地解释了这一点。

我建议创建NSDictionary类的扩展名,如:

#import <Foundation/Foundation.h>

@interface NSDictionary (Safety)

- (id)safeObjectForKey:(id)aKey;

@end

执行文件:

#import "NSDictionary+Safety.h"

@implementation NSDictionary (Safety)

- (id)safeObjectForKey:(id)aKey {
  NSObject *object = self[aKey];

  if (object == [NSNull null]) {
    return nil;
  }

  return object;
}

@end

而不是在代码中使用[dictionary objectForKey:@"keyName"];,而是使用

[dictionary safeObjectForKey:@"keyName"];

这样,正如Tommy解释的那样,你将向nil发送一个方法调用,这不会使应用程序崩溃,但是你的对象会得到一个零值。

希望这有帮助。

答案 2 :(得分:7)

以下答案对我有用:

https://stackoverflow.com/a/2784675/936957

if ([dictionary objectForKey:key]) {
    // previously stored data for "key"
}

另请注意,您可以使用

获取字典中的数组
[dictionary allKeys]

答案 3 :(得分:6)

每当我尝试检查从字典返回的对象是否为空时,我这样做:

id obj = [myDictionary objectForKey:entityKeyName];
if (obj == [NSNull null]) {
    // do something 
}

然后在您的代码中,它将是:

NSDictionary *result;
NSString *myImageURL = [result objectForKey:@"url"];
if (myImageURL == [NSNull null])
     myImageURL = @"";

这就是我在你的代码中所做的。

另外,确定是否定义了NSDictionary结果?在您的代码中,它没有任何设置。它只是被定义为您计划使用调用结果的变量

答案 4 :(得分:4)

如果某个键的对象不存在,NSDictionary将返回nilNSNull是一个实际的对象,因此是一个独特的东西。这就像能够记录有值和值为空的区别,而不是记录是否有值。它还依赖于你在C语言中思考指向对象的指针而不仅仅是一个对象,所以从那个角度来看,它并不完全在语义上令人愉悦。

在Objective-C中,您可以向nil发送任何消息,结果保证为nil(或0)。因此,如果您的代码旨在确保您有一个安全的对象引用,就像在C ++中那样,那么您所做的就是不必要的。复合语句如:

object = [[Type alloc] init];

总是显式安全,即使alloc失败并返回nil。所有这一切都是因为对init的调用根本不会做任何事情,而对象最终会得到值nil,因为init发送给{{nil 1}}也是nil

话虽如此,比尔和伊曼纽尔提供的答案应该是正确的。将结果直接与nil或隐式地比较为零。如果你以后遇到崩溃,我猜是因为你期望myImageUrlmyImageNSString以外的其他类型(我注意到你使用了无类型原始代码中的id并向他们发送他们没有回复的消息。

答案 5 :(得分:2)

NSDictionary *result;
NSString *myImageURL = [result objectForKey:@"url"];
if (myImageURL == NULL)
    myImageURL = @"";

NSString *myImage = [result objectForKey:@"image"];
if (myImageURL == NULL)
    myImage = @"";

看看是否有效,而不是过度使用NULL类。

答案 6 :(得分:2)

这另一个选择:

if (![result objectForKey:@"image"])
    {
        NSLog(@"doesn't exist");
    }
    if ([result objectForKey:@"image"])
    {
        NSLog(@"exist");
    }

答案 7 :(得分:1)

这对我不起作用,我这样想出来了

id myImageURL = [result objectForKey:@"url"];
if ([myImageURL isKindOfClass:[NSNull class]])  
    myImageURL = @"";

答案 8 :(得分:1)

好的,这是@Iomec差不多的实际答案

UIImage *myImage = ([result objectForKey:@"image"] != [NSNull null] ? [result objectForKey:@"image"] : nil);

这是实际的正确答案,因为它是null,当你说myImage = [receivedObject ...]时;那么如果myImage = nil,你实际上是将一个空值(nil)转换为一个异常的类,如果不是一个正在运行的bug。

你应该: 1)测试NSNull空值 2)如果不是,则分配

如果你的代码还没有出现问题,那么当你有一天在后台运行8个应用程序时,它就会投入生产。

答案 9 :(得分:0)

我遇到了与JSONKit相同的问题。那里的实施是

 - (id)objectForKey:(id)aKey
{
  [...]
  return((entryForKey != NULL) ? entryForKey->object : NULL);
}

因此,如果对象不存在,这肯定会返回NULL。我检查它如下

NSArray* array = [myDictionary objectForKey:@"a"];
if((NSNull*)arrays!=[NSNull null])
{
  [...]
}

答案 10 :(得分:0)

dataLabels: {
    enabled: true,
    color: 'black',
    style: { fontSize: '8px' },
    formatter: function () {
        return this.key + '<br> ' + Math.round(this.percentage * 10) / 10 + '%';
    }
},

答案 11 :(得分:0)

可能希望通过检查以确保它不是字符串而不仅仅检查它是否为零来增加一点安全性。 (以确保它不是您可能不想要的数字或其他任何内容。)

id myImageURL = [result objectForKey:@"url"];
if (![myImageURL isKindOfClass:[NSString class]]) {  
    myImageURL = @"";
}

答案 12 :(得分:0)

当您在可为空的字典中调用objectForKey时,应用程序崩溃了,因此我通过这种方式解决了这个问题,以避免崩溃。

- (instancetype)initWithDictionary:(NSDictionary*)dictionary {
id object = dictionary;

if (dictionary && (object != [NSNull null])) {
    self.name = [dictionary objectForKey:@"name"];
    self.age = [dictionary objectForKey:@"age"];
}
return self;

}