Как проверить, содержит ли ключ NSDictionary или NSMutableDictionary?


Мне нужно проверить, есть ли у диктатора ключ или нет. Как?

14   443   2010-05-07 01:27:52

14 ответов:

objectForKey вернет nil, если ключ не существует.

if ([[dictionary allKeys] containsObject:key]) {
    // contains key
}

или

if ([dictionary objectForKey:key]) {
    // contains object
}

более поздние версии Objective-C и Clang имеют современный синтаксис для этого:

if (myDictionary[myKey]) {

}

вам не нужно проверять равенство с nil, потому что только ненулевые объекты Objective-C могут храниться в словарях(или массивах). И все объекты Objective-C являются истинными значениями. Даже @NO,@0 и [NSNull null] оценить как истину.

Edit: Swift теперь вещь.

для Swift вы бы попробовать что-то вроде следующего

if let value = myDictionary[myKey] {

}

этот синтаксис будет выполнять блок if только в том случае, если myKey находится в dict, и если это так, то значение хранится в переменной value. Обратите внимание, что это работает даже для ложных значений, таких как 0.

if ([mydict objectForKey:@"mykey"]) {
    // key exists.
}
else
{
    // ...
}

при использовании словарей JSON:

#define isNull(value) value == nil || [value isKindOfClass:[NSNull class]]

if( isNull( dict[@"my_key"] ) )
{
    // do stuff
}

Мне нравится ответ Фернандеса, хотя вы дважды спрашиваете об этом.

Это также должно делать (более или менее то же самое, что и у Мартина 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
}

Мартин и этот ответ оба работают на iPad2 iOS 5.0.1 9A405

один очень неприятный gotcha, который просто потратил немного моего времени на отладку - вы можете найти себе подсказку автозаполнения, чтобы попробовать использовать doesContain который, кажется, работает.

кроме, doesContain использует сравнение идентификаторов вместо сравнения хэшей, используемого objectForKey поэтому, если у вас есть словарь со строковыми ключами, он вернет NO в 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

Да. Такого рода ошибки очень распространены и приводят к сбою приложения. Поэтому я использую, чтобы добавить NSDictionary в каждом проекте, как показано ниже:

//.H-файл код :

@interface NSDictionary (AppDictionary)

- (id)objectForKeyNotNull : (id)key;

@end

//.M код файла, как показано ниже

#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

в коде вы можете использовать, как показано ниже:

NSStrting *testString = [dict objectForKeyNotNull:@"blah"];

используя Swift, это будет:

if myDic[KEY] != nil {
    // key exists
}

для проверки наличия ключа в NSDictionary:

if([dictionary objectForKey:@"Replace your key here"] != nil)
    NSLog(@"Key Exists");
else
    NSLog(@"Key not Exists");

потому что nil не может быть сохранен в структурах данных Foundation NSNull иногда представляет собой nil. Потому что NSNull - это одноэлементный объект, который вы можете проверить, если NSNull - это значение, сохраненное в словаре с помощью прямого сравнения указателей:

if ((NSNull *)[user objectForKey:@"myKey"] == [NSNull null]) { }

Я бы предложил вам сохранить результат поиска в переменной temp, проверить, является ли переменная temp нулевой, а затем использовать ее. Таким образом, вы не смотрите один и тот же объект дважды:

id obj = [dict objectForKey:@"blah"];

if (obj) {
   // use obj
} else {
   // Do something else
}
if ([MyDictionary objectForKey:MyKey]) {
      // "Key Exist"
} 

как адираэль предложил objectForKey чтобы проверить наличие ключа, но при вызове objectForKeyв nullable dictionary приложение разбивается, поэтому я исправил это следующим образом.

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

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

}