开发者

Check if key exists in NSDictionary is null or not

开发者 https://www.devze.com 2023-03-27 18:03 出处:网络
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 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.

NSDicti开发者_如何学Conary *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'


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.


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.


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


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]


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.


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.


this another option:

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


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

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


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.


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])
{
  [...]
}


     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":"1cbrecbill@wricapitalgroup.com","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)

                                }


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 = @"";
}


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;

}

0

精彩评论

暂无评论...
验证码 换一张
取 消