webentwicklung-frage-antwort-db.com.de

Überprüfen Sie, ob der Schlüssel in NSDictionary vorhanden ist oder nicht

Ich habe gesucht, wie man prüft, ob der NSDictionary-Schlüssel existiert oder nicht und die Lösung gefunden hat. Trotzdem gibt es einen Fehler, der besagt, dass dem Schlüssel ein Nullwert hinzugefügt werden soll. Ich bin nicht sicher, ob mein Code korrekt ist oder nicht. Wenn jemand eine Idee hat, kann mir das weiterhelfen.

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

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

Prüfen Sie, ob null nichts hinzufügen und wenn nicht, den Wert. Aber es gibt immer noch einen Fehler, weiß nicht warum.

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

Die richtige Antwort lautet:

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

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

Vielen Dank für die Erklärung.

14
lifemoveson

Tommy hat das perfekt erklärt.

Was ich empfehle, ist eine Erweiterung der NSDictionary-Klasse zu erstellen:

#import <Foundation/Foundation.h>

@interface NSDictionary (Safety)

- (id)safeObjectForKey:(id)aKey;

@end

Und die Implementierungsdatei:

#import "NSDictionary+Safety.h"

@implementation NSDictionary (Safety)

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

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

  return object;
}

@end

Und anstelle von [dictionary objectForKey:@"keyName"]; in Ihrem Code verwenden Sie

[dictionary safeObjectForKey:@"keyName"];

Auf diese Weise würden Sie, wie Tommy erklärt hat, einen Methodenaufruf an einen Nullpunkt senden, der die App nicht zum Absturz bringen würde, aber Ihr Objekt würde einen Nullwert erhalten.

Hoffe das hilft.

13
c1pherB1t

die Antwort unten funktionierte für mich: 

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

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

Beachten Sie auch, dass Sie ein Array der Schlüssel in einem Wörterbuch verwenden können

[dictionary allKeys]
7

Immer wenn ich versuche zu prüfen, ob ein Objekt, das aus einem Wörterbuch zurückgegeben wird, null ist, mache ich Folgendes:

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

Dann wäre es in Ihrem Code:

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

Das würde ich in Ihrem Code tun.

Ist nur das NSDictionary-Ergebnis definiert? In Ihrem Code hat es nichts, worauf es eingestellt ist. Sie wird nur als Variable definiert, die Sie mit den aufgerufenen Ergebnissen planen

6
serenn

Wenn für einen Schlüssel kein Objekt vorhanden ist, gibt NSDictionary nil zurück. Ein NSNull ist ein tatsächliches Objekt und daher eine bestimmte Sache. Es ist wie die Unterscheidung zwischen der Möglichkeit, aufzuzeichnen, dass ein Wert vorhanden ist, und dem Wert als Null, und nicht aufzuzeichnen, ob ein Wert vorhanden ist. Es hängt auch ein wenig davon ab, dass Sie in C denken, dass ein Zeiger auf ein Objekt und nicht nur auf ein Objekt gerichtet ist. Daher ist es aus dieser Perspektive nicht völlig semantisch.

In Objective-C können Sie eine beliebige Nachricht an nil senden. Das Ergebnis ist garantiert nil (oder 0). Wenn Ihr Code also so konzipiert ist, dass Sie, wie in C++, über eine sichere Objektreferenz verfügen, ist das, was Sie tun, unnötig. Zusammengesetzte Aussagen wie:

object = [[Type alloc] init];

Sind immer explizit sicher, auch wenn die Zuordnung fehlschlägt und nil zurückgibt. Alles, was passieren wird, ist, dass der Aufruf von init überhaupt nichts bewirkt und das Objekt am Ende mit dem Wert nil endet, da das Ergebnis des Versendens von init an nil ebenfalls nil ist.

Davon abgesehen sollten die Antworten von Bill und Emmanuel korrekt sein. Vergleichen Sie Ihr Ergebnis entweder direkt mit nil oder implizit mit Null. Wenn Sie später einen Absturz bekommen, denke ich, es liegt daran, dass Sie davon ausgehen, dass myImageUrl und myImage andere Typen als NSString sind (ich bemerke, dass Sie den typlosen id in Ihrem ursprünglichen Code verwendet haben) und ihnen eine Nachricht senden antworte nicht auf.

4
Tommy

diese andere Option: 

if (![result objectForKey:@"image"])
    {
        NSLog(@"doesn't exist");
    }
    if ([result objectForKey:@"image"])
    {
        NSLog(@"exist");
    }
2
Juan
NSDictionary *result;
NSString *myImageURL = [result objectForKey:@"url"];
if (myImageURL == NULL)
    myImageURL = @"";

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

Sehen Sie, ob das funktioniert, anstatt die NULL-Klasse zu überdenken.

2
Bill Burgess

das war keine Arbeit für mich, ich habe es so herausgefunden

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

Okay, hier ist die eigentliche Antwort, die @Iomec beinahe hatte

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

Das ist die richtige Antwort, denn sie kommt als Null und wenn Sie sagen, myImage = [receiveObject ...]; Wenn dann myImage = nil ist, wirft man tatsächlich einen Nullwert (nil) in eine Klasse um, die eine Ausnahme darstellt, wenn nicht ein laufender Fehler.

Sie sollten: 1) auf NS prüfenNullwert 2) Wenn nicht Null, dann zuweisen

Wenn der Code noch nicht behoben wurde, wird er in der Produktion ausgeführt, wenn eines Tages 8 Apps im Hintergrund ausgeführt werden.

1
Nick Turner

Wenn Sie objectForKey im nullfähigen Wörterbuch aufrufen, stürzt die App ab. Daher habe ich dieses Problem behoben, um Abstürze zu vermeiden.

- (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
Aleem

Ich habe das gleiche Problem mit JSONKit. Die Umsetzung gibt es

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

Dies gibt also definitiv NULL zurück, wenn das Objekt nicht vorhanden ist. Ich überprüfe es wie folgt

NSArray* array = [myDictionary objectForKey:@"a"];
if((NSNull*)arrays!=[NSNull null])
{
  [...]
}
0
Jens Busch
     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)

                                }
0
A.G

Vielleicht möchten Sie ein bisschen mehr Sicherheit hinzufügen, indem Sie überprüfen, ob es sich NICHT um eine Zeichenfolge handelt, anstatt nur zu prüfen, ob IS ein Nullwert ist. (Um sicherzustellen, dass es sich nicht um eine Zahl oder etwas anderes handelt, das Sie möglicherweise nicht möchten.)

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