I need to check if an dict has a key or not. How?
-
4(Just for anyone googling to here. Note that this is a very **old question**. SaintMacintosh answer below is the state of the art, it is five years ahead of this QA. Hope it helps.) – Fattie Apr 16 '14 at 13:15
-
1Actually, Andy Dent's answer also gives the state of the art, and more context. And it did this earlier than SaintMacintosh. Do yourself a favor an scroll down a little more. – Peter Kämpf Apr 27 '14 at 08:35
-
1He uses: keysByName[test] != nil the != nil check is redundant and IMHO less readable. I just wanted to share the TL;DR version for people looking the syntax. – Andrew Hoos Jul 30 '14 at 20:17
-
I agree with @SaintMacintosh. his answer is much more succinct. – SAS Jan 29 '15 at 20:56
-
If you wish to check if the `NSDictionary` contains any key (non-specific) you should use `[dictionary allKeys].count == 0` If the `count` is `0` there are no keys in the `NSDictionary`. – Aleksander Azizi Nov 10 '15 at 08:38
16 Answers
-
29And what if the key does exist, but it's corresponding value is nil? – Fyodor Soikin May 06 '10 at 21:30
-
234That's not possible. You can't add nil to a NSDictionary. You would have to use `[NSNull null]` instead. – Ole Begemann May 06 '10 at 21:39
-
10@fyodor an nsdictionay will throw an NSInvalidArgumentException if you attempt to insert a nil value, so there should never be a case where a key exists, but the corresponding value is nil. – Brad The App Guy May 06 '10 at 22:50
-
3Don't you want to use valueForKey, as that would call objectForKey if necessary? – Raffi Khatchadourian Dec 21 '11 at 00:39
-
7You absolutely do NOT NEVER EVER want to use valueForKey for a JSON dictionary. That's because JSON can contain _any_ string as a key. For example, if it contains "@count" as a key, then objectForKey:@"@count" will give the correct value, but valueForKey:@"@count" will give the number of key/value pairs. – gnasher729 Apr 04 '14 at 18:16
-
To explain again, **IF THERE IS A KEY**, say "keyName", and the value of that key happens to be [NSNull null] (or indeed anything else) .. then ........... **THE KEY DOES EXIST**. The question is how to tell if the KEY EXISTS. If the "KEY EXISTS" and the value is nil {which is not possible anyway in json}, then the "key exists". – Fattie Apr 16 '14 at 13:17
-
@JoeBlow the part you're misunderstanding is that [NSNull null] is not the same as nil. You cannot add nil to a dictionary, but you can add [NSNull null]. – korbonix Oct 03 '14 at 16:34
-
-
1@BenLeggiero `dictionary[key]` is the Objective-C modern syntax for `[dictionary objectForKey:key]`this also helps to avoid using wrong methods for this purpose such as `valueForKey` (which is for KVC and is out of the scope of this question). – tomacco Nov 09 '18 at 19:31
if ([[dictionary allKeys] containsObject:key]) {
// contains key
/* Don't use this solution. Look for more details in comments. */
}
or
if ([dictionary objectForKey:key]) {
// contains object
}

- 8,647
- 6
- 38
- 44
-
104
-
8read: example one in this answer should be considered illegal (O(n) instead of O(1)) – Hertzel Guinness Nov 28 '13 at 12:45
-
5performance is very relevant. It may be very true that this exact line is irrelevant, but if it going to be repeated n times then all of sudden instead of it taking n time its taking n*m and you can't figure out why your program is slow. Almost everything is fast once or in small cases. But as programs grow using the wrong data structure (like array instead of dict in the first example) will end up costing you big. – Andrew Hoos May 08 '14 at 07:27
-
2Checking a dictionary(or set) for the existence of a key is expected O(1) with a worst case of O(n). Not O(log(n)). Apple's documentation clearly explains this. – Andrew Hoos Aug 12 '14 at 15:58
-
@JoeBlow _“animate the 3D Mecanim dots”_ It sounds like you're confusing Cocoa Touch/Objective-C with Unity Engine/C#. It's true that the Unity Engine is terribly inefficient on the platforms it runs on. However, it's not at all true that Objective-C/Swift applications are inherently inefficient, nor that most seasoned iOS developers aren't actively cognizant of the efficiency of their code. As for _“only relevant to the (4 living) performance programmers”_ — you're clearly not a game developer. Great graphics & gameplay at 60FPS w/o killing the battery is a continual challenge. – Slipp D. Thompson Nov 05 '16 at 23:17
-
Does [dictionary allKeys] return a Set like data structure or an Array like data structure? A Set should be O(1) query and an Array should be O(n) query. – wz366 Mar 07 '18 at 19:37
More recent versions of Objective-C and Clang have a modern syntax for this:
if (myDictionary[myKey]) {
}
You do not have to check for equality with nil, because only non-nil Objective-C objects can be stored in dictionaries(or arrays). And all Objective-C objects are truthy values. Even @NO
, @0
, and [NSNull null]
evaluate as true.
Edit: Swift is now a thing.
For Swift you would try something like the following
if let value = myDictionary[myKey] {
}
This syntax will only execute the if block if myKey is in the dict and if it is then the value is stored in the value variable. Note that this works for even falsey values like 0.

- 1,510
- 2
- 15
- 23
-
Thanks for this! I am just curious, but I can't find this behavior documented in the objective-c class reference https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDictionary/ AM I just blind? – irh Aug 07 '14 at 14:36
-
2No you are not blind. It is not emphasized. But visible [here](http://clang.llvm.org/docs/ObjectiveCLiterals.html)(clang) and [here](https://developer.apple.com/library/ios/releasenotes/ObjectiveC/ModernizationObjC/AdoptingModernObjective-C/AdoptingModernObjective-C.html)(modern objc: very bottom) and [here](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/FoundationTypesandCollections/FoundationTypesandCollections.html)(collections guide: search dictionary) – Andrew Hoos Aug 07 '14 at 18:49
if ([mydict objectForKey:@"mykey"]) {
// key exists.
}
else
{
// ...
}

- 112,638
- 29
- 165
- 179
When using JSON dictionaries:
#define isNull(value) value == nil || [value isKindOfClass:[NSNull class]]
if( isNull( dict[@"my_key"] ) )
{
// do stuff
}

- 2,781
- 1
- 34
- 49
I like Fernandes' answer even though you ask for the obj twice.
This should also do (more or less the same as Martin's A).
id obj;
if ((obj=[dict objectForKey:@"blah"])) {
// use obj
} else {
// Do something else like creating the obj and add the kv pair to the dict
}
Martin's and this answer both work on iPad2 iOS 5.0.1 9A405

- 81
- 1
- 3
Yes. This kind of errors are very common and lead to app crash. So I use to add NSDictionary in each project as below:
//.h file code :
@interface NSDictionary (AppDictionary)
- (id)objectForKeyNotNull : (id)key;
@end
//.m file code is as below
#import "NSDictionary+WKDictionary.h"
@implementation NSDictionary (WKDictionary)
- (id)objectForKeyNotNull:(id)key {
id object = [self objectForKey:key];
if (object == [NSNull null])
return nil;
return object;
}
@end
In code you can use as below:
NSStrting *testString = [dict objectForKeyNotNull:@"blah"];
One very nasty gotcha which just wasted a bit of my time debugging - you may find yourself prompted by auto-complete to try using doesContain
which seems to work.
Except, doesContain
uses an id comparison instead of the hash comparison used by objectForKey
so if you have a dictionary with string keys it will return NO to a doesContain
.
NSMutableDictionary* keysByName = [[NSMutableDictionary alloc] init];
keysByName[@"fred"] = @1;
NSString* test = @"fred";
if ([keysByName objectForKey:test] != nil)
NSLog(@"\nit works for key lookups"); // OK
else
NSLog(@"\nsod it");
if (keysByName[test] != nil)
NSLog(@"\nit works for key lookups using indexed syntax"); // OK
else
NSLog(@"\nsod it");
if ([keysByName doesContain:@"fred"])
NSLog(@"\n doesContain works literally");
else
NSLog(@"\nsod it"); // this one fails because of id comparison used by doesContain

- 1,493
- 1
- 12
- 21

- 17,578
- 6
- 88
- 115
For checking existence of key in NSDictionary:
if([dictionary objectForKey:@"Replace your key here"] != nil)
NSLog(@"Key Exists");
else
NSLog(@"Key not Exists");

- 16,329
- 10
- 59
- 65
-
2This is really just a repeat of [this existing answer](https://stackoverflow.com/a/2784664). – Pang Mar 28 '18 at 07:40
Because nil cannot be stored in Foundation data structures NSNull
is sometimes to represent a nil
. Because NSNull
is a singleton object you can check to see if NSNull
is the value stored in dictionary by using direct pointer comparison:
if ((NSNull *)[user objectForKey:@"myKey"] == [NSNull null]) { }

- 1,510
- 2
- 15
- 23

- 216
- 3
- 8
-
1Did not work out when I used it with NSMutableArray as object for my key. – pa12 Dec 19 '12 at 23:05
-
4Why on earth did this get upvoted? It's just plain wrong. This check will return true if the singleton `NSNull` instance has been stored in the dictionary as the value for key `@"myKey"`. That's a totally different thing to the key `@"myKey"` not being in the dictionary - indeed the two are mutually exclusive. – Mark Amery Oct 29 '13 at 11:40
-
Since this still has five votes while being totally wrong, I can only repeat what Mark says: This code tests whether the dictionary contains a key with a null value, which is totally different from not containing the key at all. – gnasher729 Apr 04 '14 at 18:19
-
-
This answer has been edited to clarify what it does do (check for NSNull in a dict) and what it does not do(check for a value in a dict) – Andrew Hoos Jun 22 '16 at 20:59
Solution for swift 4.2
So, if you just want to answer the question whether the dictionary contains the key, ask:
let keyExists = dict[key] != nil
If you want the value and you know the dictionary contains the key, say:
let val = dict[key]!
But if, as usually happens, you don't know it contains the key - you want to fetch it and use it, but only if it exists - then use something like if let
:
if let val = dict[key] {
// now val is not nil and the Optional has been unwrapped, so use it
}

- 3,014
- 3
- 21
- 36
As Adirael suggested objectForKey
to check key existance but When you call objectForKey
in nullable dictionary, app gets crashed so I fixed this from following way.
- (instancetype)initWithDictionary:(NSDictionary*)dictionary {
id object = dictionary;
if (dictionary && (object != [NSNull null])) {
self.name = [dictionary objectForKey:@"name"];
self.age = [dictionary objectForKey:@"age"];
}
return self;
}

- 3,173
- 5
- 33
- 71
I'd suggest you store the result of the lookup in a temp variable, test if the temp variable is nil and then use it. That way you don't look the same object up twice:
id obj = [dict objectForKey:@"blah"];
if (obj) {
// use obj
} else {
// Do something else
}

- 231
- 2
- 4
if ([MyDictionary objectForKey:MyKey]) {
// "Key Exist"
}

- 11,704
- 4
- 46
- 60

- 1,090
- 7
- 7
-
1This is really just a repeat of [this existing answer](https://stackoverflow.com/a/2784664). – Pang Mar 28 '18 at 07:41
if ( [dictionary[@"data"][@"action"] isKindOfClass:NSNull.class ] ){
//do something if doesn't exist
}
This is for nested dictionary structure

- 71
- 2
- 8