2017-10-25 2 views
3

ich diesen Code JSON-Format zum Lesen:Was bedeutet __NSSingleObjectArrayI in Objective C? wenn ich versuche, eine Json

{ 
    "weather": [{ 
     "description": "clear sky", 
     "icon": "01n" 
    }], 
    "base": "stations", 
    "main": { 
     "temp": 285.514 
    }, 
    "clouds": { 
     "all": 0 
    }, 
    "dt": 1485792967, 
    "id": 1907296 
} 

Und ich will Symbol string (01n)

Und verwenden Sie diesen Code retrive:

@property(nonatomic,strong) NSString *cityImageName; 

self.cityImageName = [[dataJson valueForKey:@"weather"] valueForKey:@"icon"]; 

Und später, wenn ich die Variable print prüfe:

<__NSSingleObjectArrayI 0x604000009890>(
01n 
) 

Wie kann ich die Zeichenfolge direkt erhalten? nicht wie ein __NSSingleObjectArrayI

+0

Warum verwenden Sie 'valueForKey:' anstelle von 'objectForKey:'? – rmaddy

+0

Während die zwei Antworten richtig sind und erklären, was schief gelaufen ist ('valueForKey:'), um Ihre Frage zu beantworten, ist es eine interne Klasse, die sagt: "NSArray" "Unveränderlich" (für das "Ich" am Ende, gegen Mutable) Version, aber das ist implizit mit "NSArray" vs "NSMutableArray") und optimiert für nur ein Objekt ("SingleObject" -Teil). – Larme

Antwort

3

Sie im Schlüsselwert verfing Coding-Trap.

valueForKey hat ein spezielles Verhalten. Auf ein Array angewendet, gibt es immer ein Array von Werten für den angegebenen Schlüssel zurück.

Verwenden Sie niemals valueForKey, es sei denn, Sie beabsichtigen, KVC zu verwenden. Die empfohlene Syntax lautet objectForKey oder - vorzugsweise - Schlüsselabonnement und im Falle des Array-Indexabonnements. In diesem Fall möchten Sie den Wert für den Schlüssel icon des ersten Elements im Array für Schlüssel weather abrufen.

self.cityImageName = dataJson[@"weather"][0][@"icon"]; 

Allerdings würde ich einen Scheck hinzufügen, wenn das Array nicht leer ist eine Out-of-Range-Ausnahme

NSArray *weather = dataJson[@"weather"]; 
if (weather && weather.count > 0) { 
    self.cityImageName = weather[0][@"icon"]; 
} 
+0

Dies ist eine ausgezeichnete Antwort. Jetzt verstehe ich, wie ich mit diesen Situationen arbeiten kann. – Fabio

2

__NSSingleObjectArrayI ist eine der Implementierungen der NSArrayclass cluster zu vermeiden. Es ist nicht wirklich wichtig für diese Frage, außer zu wissen, dass es ein Array ist.

Der Grund Sie einen Array bekommen (ein Element) anstelle einer Zeichenfolge ist, weil die JSON mit dem Sie arbeiten sind enthält einen Array mit einem Wörterbuch in der es:

"weather": [{ 
    "description": "clear sky", 
    "icon": "01n" 
}], 

Hinweis: die eckigen Klammern, die die geschweiften Klammern umgeben. So

, wenn Sie anrufen [dataJson valueForKey:@"weather"] Sie das Objekt zurück, das diesen Teil des JSON darstellen:

[ { "description": "clear sky", "icon": "01n" } ] 

die in diesem Fall ist, wurde als NSArray, die eine NSDictionary mit zwei Schlüsseln entschlüsselt.

Wenn Sie dann valueForKey: on that array nennen es

Gibt ein Array, das die Ergebnisse von Aufrufen valueForKey: enthält Objekte mit key auf jedem der Arrays.

Mit anderen Worten, weil eine Anordnung von [dataJson valueForKey:@"weather"] eines Wörterbuch ist, ist [[dataJson valueForKey:@"weather"] valueForKey:@"icon"] ein Array von nur der Wert für die "icon" Schlüssel in diesem Wörterbuch.

Wenn der JSON, mit dem Sie arbeiten, immer dieses Format hat, können Sie firstObject aus dem Array abrufen, um die erste Zeichenfolge zu erhalten (oder nil, wenn das Array leer war).