Mam ciąg JSON (z PHP, json_encode()
który wygląda tak:
[{"id": "1", "name":"Aaa"}, {"id": "2", "name":"Bbb"}]
Chcę przeanalizować to w jakiejś strukturze danych dla mojej aplikacji na iPhone'a. Myślę, że najlepszą rzeczą dla mnie byłoby posiadanie tablicy słowników, więc zerowym elementem tablicy jest słownik z kluczami "id" => "1"
i "name" => "Aaa"
.
Nie rozumiem jednak, jak NSJSONSerialization
przechowują dane. Oto mój dotychczasowy kod:
NSError *e = nil;
NSDictionary *JSON = [NSJSONSerialization
JSONObjectWithData: data
options: NSJSONReadingMutableContainers
error: &e];
To jest coś, co widziałem jako przykład na innej stronie internetowej. Próbowałem odczytać JSON
obiekt, wypisując liczbę elementów i tym podobne, ale zawsze otrzymuję EXC_BAD_ACCESS
.
Jak użyć NSJSONSerialization
do przeanalizowania powyższego JSON i przekształcenia go w strukturę danych, o której wspomniałem?
ios
objective-c
json
nsdictionary
Logan Serman
źródło
źródło
Odpowiedzi:
Twój główny obiekt json nie jest słownikiem, ale tablicą:
To może dać ci jasny obraz tego, jak sobie z tym poradzić:
źródło
[JSON count]
zwracać zamiast po prostu dać mi EXC_BAD_ACCESS?!jsonArray
i wypisałem błąd. Powinno to spowodować wyświetlenie wszelkich błędów, które wystąpiły podczas analizowania.jsonArray
tego pliku, powinien być automatycznie wydany.To jest mój kod do sprawdzania, czy odebrany plik json jest tablicą lub słownikiem:
Wypróbowałem to dla opcji: kNilOptions i NSJSONReadingMutableContainers i działa poprawnie dla obu.
Oczywiście rzeczywisty kod nie może być taki, gdy tworzę wskaźnik NSArray lub NSDictionary w bloku if-else.
źródło
Mi to pasuje. Twoim
data
obiektem jest prawdopodobnienil
i, jak zauważył rckoenes, głównym obiektem powinna być (zmienna) tablica. Zobacz ten kod:(Musiałem pominąć cudzysłowy w ciągu JSON z ukośnikami odwrotnymi).
źródło
Twój kod wydaje się być w porządku, ale wynikiem jest an
NSArray
, a nie anNSDictionary
, oto przykład:Pierwsze dwa wiersze po prostu tworzą obiekt danych z kodem JSON, tak samo, jak przy odczytywaniu go z sieci.
Zawartość NSLog (lista słowników):
źródło
NSJSONReadingMutableLeaves
„Określa, że ciągi liści w grafie obiektów JSON są tworzone jako wystąpienia NSMutableString.”NSJSONReadingMutableContainers
:: „Określa, że tablice i słowniki są tworzone jako zmienne obiekty”.W powyższych danych JSON pokazujesz, że mamy tablicę zawierającą liczbę słowników.
Aby go przeanalizować, musisz użyć tego kodu:
Do szybkiego 3/3 +
źródło
Poniższy kod pobiera obiekt JSON z serwera WWW i analizuje go do NSDictionary. Użyłem API openweathermap, które zwraca prostą odpowiedź JSON dla tego przykładu. Dla uproszczenia ten kod używa synchronicznych żądań.
źródło
@rckoenes już pokazał, jak poprawnie pobrać dane z ciągu JSON.
Na pytanie, które zadałeś:
EXC_BAD_ACCESS
prawie zawsze pojawia się, gdy próbujesz uzyskać dostęp do obiektu po tym, jak został on [automatycznie] zwolniony. Nie jest to specyficzne dla [de-] serializacji JSON, ale raczej ma związek z pobraniem obiektu i uzyskaniem do niego dostępu po jego wydaniu. Fakt, że pochodzi z JSON, nie ma znaczenia.Istnieje wiele stron opisujących, jak to debugować - chcesz Google (lub SO)
obj-c zombie objects
, aw szczególnościNSZombieEnabled
, które okażą się nieocenione w określeniu źródła twoich obiektów zombie. (Nazywa się „Zombie”, gdy zwalniasz obiekt, ale trzymasz do niego wskaźnik i próbujesz odwołać się do niego później.)źródło
Swift 2.0 na Xcode 7 (Beta) z blokiem do / try / catch:
źródło
UWAGA: dla Swift 3 . Twój ciąg JSON zwraca Array zamiast Dictionary. Wypróbuj następujące rozwiązania:
źródło
źródło
Wydaje się, że problem dotyczy automatycznego zwalniania obiektów. NSJSONSerialization JSONObjectWithData to oczywiście tworzenie niektórych autoreleased obiektów i przekazywanie ich z powrotem. Jeśli spróbujesz przenieść to do innego wątku, nie zadziała, ponieważ nie można go cofnąć w innym wątku.
Sztuczka może polegać na zrobieniu modyfikowalnej kopii tego słownika lub tablicy i użyciu jej.
Traktowanie NSDictionary jako NSArray nie spowoduje powstania wyjątku złego dostępu, ale zamiast tego prawdopodobnie spowoduje awarię po wywołaniu metody.
Być może opcje nie mają tutaj znaczenia, ale lepiej jest podać NSJSONReadingMutableContainers | NSJSONReadingMutableContainers | NSJSONReadingAllowFragments, ale nawet jeśli są to obiekty autoreleased, może to nie rozwiązać tego problemu.
źródło
zły przykład, powinno wyglądać mniej więcej tak {"id": 1, "name": "something as name"}
liczba i ciąg są mieszane.
źródło