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 objectForKey
in 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;
}
精彩评论