检查 NSDictionary 中是否存在 key 是否为 null

发布于 2024-11-29 04:16:21 字数 1232 浏览 0 评论 0原文

我确实搜索了如何检查 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'

I did search on how to check if NSDictionary key exists or not and came up with the solution. But still it throws me an error saying adding null value to the key.
I am not sure if my code is correct or not. If anyone has any idea about this can help me.

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

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

Check if null add nothing and if not add the value. But it still gives me an error dont know why.

/****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'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(13

乖不如嘢 2024-12-06 04:16:21

正确答案是:

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

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

谢谢您的所有解释。

Correct answer is :

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

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

Thank you for all the explanation.

波浪屿的海角声 2024-12-06 04:16:21

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

我建议创建 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 发送方法调用,这不会使应用程序崩溃,但您的对象将获得 nil 值。

希望这有帮助。

Tommy explained this perfectly.

What I recommend is create an extension of the NSDictionary class like:

#import <Foundation/Foundation.h>

@interface NSDictionary (Safety)

- (id)safeObjectForKey:(id)aKey;

@end

And the implementation file:

#import "NSDictionary+Safety.h"

@implementation NSDictionary (Safety)

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

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

  return object;
}

@end

And instead of using [dictionary objectForKey:@"keyName"]; in your code, use

[dictionary safeObjectForKey:@"keyName"];

This way, as Tommy explained, you'd be sending a method call to a nil which wouldn't crash the app but your object would get a nil value.

Hope this helps.

素手挽清风 2024-12-06 04:16:21

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

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

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

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

这就是我将在您的代码中执行的操作。

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

Whenever I try to check if an object being returned from a dictionary is null, I do this:

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

Then in your code, it would be:

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

That's what I would do in your code.

Also, just making sure, is the NSDictionary result defined? In your code, it doesn't have anything it's being set to. It's just being defined as variable you plan on using called results

终难愈 2024-12-06 04:16:21

下面的答案对我有用:

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

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

另请注意,您可以获得使用字典中的键数组

[dictionary allKeys]

the answer below worked for me:

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

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

Also note that you can get array of the keys in a dictionary using

[dictionary allKeys]
九公里浅绿 2024-12-06 04:16:21

如果某个键不存在对象,NSDictionary 将返回nilNSNull 是一个实际的对象,因此是一个不同的东西。这就好比能够记录有一个值并且该值为null,和不记录是否有一个值之间的区别。它还取决于您用 C 术语来思考指向对象的指针的间接寻址而不仅仅是对象,因此从这个角度来看,它在语义上并不完全令人满意。

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

object = [[Type alloc] init];

始终显式安全,即使 alloc 失败并返回 nil。所发生的情况是,对 init 的调用根本不会执行任何操作,并且对象将以值 nil 结束,因为 的发送结果>initnil 也是 nil

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

If an object doesn't exist for a key, NSDictionary will return nil. An NSNull is an actual object, and therefore a distinct thing. It's like the distinction between being able to record that there was a value and the value as null, and not recording whether there was a value. It also rests a bit on you thinking in C terms of the indirection of a pointer to an object rather than just an object, so it's not completely semantically pleasing from that perspective.

In Objective-C, you may send any message to nil and the result is guaranteed to be nil (or 0). So if your code is designed to ensure that you have a safe object reference, as you might in C++, then what you're doing is unnecessary. Compound statements like:

object = [[Type alloc] init];

Are always explicitly safe, even if alloc fails and returns nil. All that'll happen is that the call to init won't do anything at all, and object will end up with the value nil because the result of sending of init to nil is also nil.

That being said, the answers provided by Bill and Emmanuel should be correct. Compare your result either directly to nil or implicitly to zero. If you're getting a crash later on, I'll guess it's because you're expecting myImageUrl and myImage to be types other than NSString (I notice you've used the typeless id in your original code) and sending them a message they don't respond to.

双马尾 2024-12-06 04:16:21
NSDictionary *result;
NSString *myImageURL = [result objectForKey:@"url"];
if (myImageURL == NULL)
    myImageURL = @"";

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

看看这是否有效,而不是过度考虑 NULL 类。

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

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

See if that works, rather than overthinking the NULL class.

音盲 2024-12-06 04:16:21

这是另一个选择:

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

this another option:

if (![result objectForKey:@"image"])
    {
        NSLog(@"doesn't exist");
    }
    if ([result objectForKey:@"image"])
    {
        NSLog(@"exist");
    }
星星的軌跡 2024-12-06 04:16:21

这对我来说不起作用,我是这样想的

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

that was not work for me, i figured it out like this

id myImageURL = [result objectForKey:@"url"];
if ([myImageURL isKindOfClass:[NSNull class]])  
    myImageURL = @"";
我也只是我 2024-12-06 04:16:21

好吧,这是@Iomec 几乎得到的实际答案

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

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

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

如果您的代码尚未出现错误,那么当您有一天在后台运行 8 个应用程序时,它将在生产环境中运行。

Alright here's the actual answer which @Iomec almost had

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

That is the actual correct answer because, it comes as null and when you say myImage = [receivedObject...]; then if myImage = nil, you are in effect casting a null value(nil) into a class which is an exception, if not a running bug.

You should:
1) test for NSNull null value
2) if not nil then assign

If you code hasn't bugged out yet, it will in production when you have 8 apps running in the background one day.

我一直都在从未离去 2024-12-06 04:16:21

我在使用 JSONKit 时遇到了同样的问题。那里的实现是

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

所以如果对象不存在,这肯定会返回 NULL。我像下面这样检查

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

I got the same issue with JSONKit. The implementation there is

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

So this will definitely return NULL if the object isn't there. I check it like the following

NSArray* array = [myDictionary objectForKey:@"a"];
if((NSNull*)arrays!=[NSNull null])
{
  [...]
}
紧拥背影 2024-12-06 04:16:21
     1. Results Dictionary after JSON parsing:

        //if hits success

        {"result":{"action":"authentication","statusCode":"200","statusMsg":"No
        error, operation
        successful.","count":1,"data":{"apiToken":"509e6d21-4f69-4ded-9f3d-4537e59e6a3a","userId":8,"role":"Bidder","firstName":"bidder","lastName":"bidder","emailAddress":"[email protected]","countiesCovered":"21,16,11,1,2,14,32,3,4,25,13,15,5,41,43,6,12,7,24,39,17,36,42,44,29,40,8,18,19,27,9,28,23,10,33,26,35,20,30,22,34,31"}}}

//Data is Dictionary inside Result


-----------------------------------------------------------------------
            I had an error showing : NULL DATACould not cast value of type 'NSNull' (0xda7058) to 'NSDictionary' (0xda6d74) and the result was
        the following.

            ({"result":{"action":"authentication","statusCode":"204","statusMsg":"Invalid
        Username or Password","count":null,"data":null}})

            I fixed the Null check of dictionary.

                                if (result.objectForKey("data") is NSNull)
                                {
            print ("NULL DATA")

                                }
                                else
                                {
                                    let data = result["data"]as! NSDictionary
                                    print (data)

                                }
     1. Results Dictionary after JSON parsing:

        //if hits success

        {"result":{"action":"authentication","statusCode":"200","statusMsg":"No
        error, operation
        successful.","count":1,"data":{"apiToken":"509e6d21-4f69-4ded-9f3d-4537e59e6a3a","userId":8,"role":"Bidder","firstName":"bidder","lastName":"bidder","emailAddress":"[email protected]","countiesCovered":"21,16,11,1,2,14,32,3,4,25,13,15,5,41,43,6,12,7,24,39,17,36,42,44,29,40,8,18,19,27,9,28,23,10,33,26,35,20,30,22,34,31"}}}

//Data is Dictionary inside Result


-----------------------------------------------------------------------
            I had an error showing : NULL DATACould not cast value of type 'NSNull' (0xda7058) to 'NSDictionary' (0xda6d74) and the result was
        the following.

            ({"result":{"action":"authentication","statusCode":"204","statusMsg":"Invalid
        Username or Password","count":null,"data":null}})

            I fixed the Null check of dictionary.

                                if (result.objectForKey("data") is NSNull)
                                {
            print ("NULL DATA")

                                }
                                else
                                {
                                    let data = result["data"]as! NSDictionary
                                    print (data)

                                }
你在看孤独的风景 2024-12-06 04:16:21

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

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

Might want to add a bit more safety by checking to make sure it is NOT a string instead of just checking if it IS a nil. (To make sure it is not a number or anything else you might not want.)

id myImageURL = [result objectForKey:@"url"];
if (![myImageURL isKindOfClass:[NSString class]]) {  
    myImageURL = @"";
}
吃不饱 2024-12-06 04:16:21

当您在可为空的字典中调用 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;

}

When you call objectForKeyin nullable dictionary, app gets crashed so I fixed this from this way to avoid from crash.

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

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

}

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