前言
NS_CLASS_AVAILABLE(10_7, 5_0) @interface NSJSONSerialization : NSObject
@available(iOS 5.0, *) public class NSJSONSerialization : NSObject
1、JSON 數據
- JSON(JavaScript Object Notation)是一種輕量級的數據交換格式。它基於 ECMAScript 的一個子集。JSON 采用完全獨立於語言的文本格式,但是也使用了類似於 C 語言家族的習慣(包括 C、C++、 C#、Java、JavaScript、Perl、Python 等)。這些特性使 JSON 成為理想的數據交換語言。易於人閱讀和編寫,同時也易於機器解析和生成(一般用於提升網絡傳輸速率)。
1.1 JSON 語法規則
- JSON 語法是 JavaScript 對象表示語法的子集。
- 數據在鍵值對中
- 數據由逗號分隔
- 花括號保存對象
- 方括號保存數組
1.2 JSON 基礎結構
-
JSON 結構有兩種,JSON 簡單說就是 javascript 中的對象和數組,所以這兩種結構就是對象和數組兩種結構,通過這兩種結構可以表示各種復雜的結構。
- 1、對象:對象在 JSON 中表示為 “{}” 括起來的內容,數據結構為 {key:value, key:value, ...} 的鍵值對的結構,在面向對象的語言中,key 為對象的屬性,value 為對應的屬性值,所以很容易理解,取值方法為 對象[key] 獲取屬性值,這個屬性值的類型可以是數字、字符串、數組、對象幾種。
- 2、數組:數組在 JSON 中表示為 “[]” 括起來的內容,數據結構為 ["java", "javascript", "vb", ...],取值方式和所有語言中一樣,使用索引獲取。字段值的類型可以是 數字、字符串、數組、對象幾種。
1.3 JSON 名稱/值對
- JSON 數據的書寫格式是:名稱/值對。
- 名稱/值對組合中的名稱寫在前面(在雙引號中),值對寫在后面(同樣在雙引號中),中間用冒號隔開:"firstName":"John"
1.4 JSON 值
- JSON 值可以是:
- 數字(整數或浮點數)
- 字符串(在雙引號中)
- 邏輯值(true 或 false)
- 數組(在方括號中)
- 對象(在花括號中)
- null
1.5 JSON 基礎示例
-
簡單地說,JSON 可以將 JavaScript 對象中表示的一組數據轉換為字符串,然后就可以在函數之間輕松地傳遞這個字符串,或者在異步應用程序中將字符串從 Web 客戶機傳遞給服務器端程序。這個字符串看起來有點兒古怪,但是 JavaScript 很容易解釋它,而且 JSON 可以表示比 "名稱/值對" 更復雜的結構。例如,可以表示數組和復雜的對象,而不僅僅是鍵和值的簡單列表。
-
1、表示名稱/值對:
-
按照最簡單的形式,可以用下面這樣的 JSON 表示 "名稱/值對":
{"firstName":"Brett"}
-
這個示例非常基本,而且實際上比等效的純文本 "名稱/值對" 占用更多的空間:
firstName=Brett
-
但是,當將多個 "名稱/值對" 串在一起時,JSON 就會體現出它的價值了。首先,可以創建包含多個 "名稱/值對" 的記錄,比如:
{"firstName":"Brett", "lastName":"McLaughlin", "email":"aaaa"}
-
從語法方面來看,這與 "名稱/值對" 相比並沒有很大的優勢,但是在這種情況下 JSON 更容易使用,而且可讀性更好。例如,它明確地表示以上三個值都是同一記錄的一部分;花括號使這些值有了某種聯系。
-
-
2、表示數組
-
當需要表示一組值時,JSON 不但能夠提高可讀性,而且可以減少復雜性。例如,假設您希望表示一個人名列表。在 XML 中,需要許多開始標記和結束標記;如果使用典型的 "名稱/值對"(就像在本系列前面文章中看到的那種名 "名稱/值對"),那么必須建立一種專有的數據格式,或者將鍵名稱修改為 person1-firstName 這樣的形式。如果使用 JSON,就只需將多個帶花括號的記錄分組在一起:
{ "people":[ {"firstName":"Brett", "lastName":"McLaughlin", "email":"aaaa"}, {"firstName":"Jason", "lastName":"Hunter", "email":"bbbb"}, {"firstName":"Elliotte", "lastName":"Harold", "email":"cccc"} ] }
-
這不難理解。在這個示例中,只有一個名為 people 的變量,值是包含三個條目的數組,每個條目是一個人的記錄,其中包含名、姓和電子郵件地址。上面的示例演示如何用括號將記錄組合成一個值。當然,可以使用相同的語法表示多個值(每個值包含多個記錄):
{ "programmers":[ {"firstName": "Brett", "lastName": "McLaughlin", "email": "aaaa"}, {"firstName": "Jason", "lastName": "Hunter", "email": "bbbb"}, {"firstName": "Elliotte", "lastName": "Harold", "email": "cccc"} ], "authors":[ {"firstName": "Isaac", "lastName": "Asimov", "genre": "sciencefiction"}, {"firstName": "Tad", "lastName": "Williams", "genre": "fantasy"}, {"firstName": "Frank", "lastName": "Peretti", "genre": "christianfiction" } ], "musicians":[ {"firstName": "Eric", "lastName": "Clapton", "instrument": "guitar"}, {"firstName": "Sergei", "lastName": "Rachmaninoff", "instrument": "piano" } ] }
-
這里最值得注意的是,能夠表示多個值,每個值進而包含多個值。但是還應該注意,在不同的主條目(programmers、authors 和 musicians)之間,記錄中實際的 "名稱/值對" 可以不一樣。JSON 是完全動態的,允許在 JSON 結構的中間改變表示數據的方式。在處理 JSON 格式的數據時,沒有需要遵守的預定義的約束。所以,在同樣的數據結構中,可以改變表示數據的方式,甚至可以以不同方式表示同一事物。
-
1.6 JSON 具體形式
-
1、對象是一個無序的 “名稱/值對” 集合
-
1)一個對象以 “{” 左括號開始,“}” 右括號結束。
-
2)每個 “名稱” 后跟一個 “:” 冒號;
-
3)“名稱/值對” 之間使用 “,” 逗號分隔。
-
例子:表示人的一個對象:
{ "姓名":"大憨", "年齡":24 }
-
-
2、數組是值(value)的有序集合
-
1)一個數組以 “[” 左中括號開始,“]” 右中括號結束。
-
2)值之間使用 “,” 逗號分隔。
-
例子:一組學生
{ "學生": [{"姓名":"小明","年齡":23}, {"姓名":"大憨","年齡":24}] } 說明:此 Json 對象包括了一個學生數組,而學生數組中的值又是兩個 Json 對象。
-
-
3、值(value)可以是雙引號括起來的字符串(string)、數值(number)、true、false、 null、對象(object)或者數組(array)。這些結構可以嵌套。
-
4、字符串(string)是由雙引號包圍的任意數量 Unicode 字符的集合,使用反斜線轉義。一個字符(character)即一個單獨的字符串(character string)。 字符串(string)與 C 或者 Java 的字符串非常相似。
-
5、數值(number)也與 C 或者 Java 的數值非常相似。除去未曾使用的八進制與十六進制格式。除去一些編碼細節。
1.7 JSON 和 XML 的比較
-
可讀性
- JSON 和 XML 的可讀性可謂不相上下,一邊是簡易的語法,一邊是規范的標簽形式,很難分出勝負。
-
可擴展性
- XML 天生有很好的擴展性,JSON 當然也有,沒有什么是 XML 可以擴展而 JSON 卻不能擴展的。不過 JSON 在 Javascript 主場作戰,可以存儲 Javascript 復合對象,有着 XML 不可比擬的優勢。
-
編碼難度
- XML 有豐富的編碼工具,比如 Dom4j、JDom 等,JSON 也有提供的工具。無工具的情況下,相信熟練的開發人員一樣能很快的寫出想要的 XML 文檔和 JSON 字符串,不過,XML 文檔要多很多結構上的字符。
-
解碼難度
-
XML 的解析方式有兩種:
- 一是通過文檔模型解析,也就是通過父標簽索引出一組標記。例如:xmlData.getElementsByTagName("tagName"),但是這樣是要在預先知道文檔結構的情況下使用,無法進行通用的封裝。
- 另外一種方法是遍歷節點(document 以及 childNodes)。這個可以通過遞歸來實現,不過解析出來的數據仍舊是形式各異,往往也不能滿足預先的要求。
- 凡是這樣可擴展的結構數據解析起來一定都很困難。
-
JSON 也同樣如此:
- 如果預先知道 JSON 結構的情況下,使用 JSON進 行數據傳遞簡直是太美妙了,可以寫出很實用美觀可讀性強的代碼。如果你是純粹的前台開發人員,一定會非常喜歡 JSON。但是如果你是一個應用開發人員,就不是那么喜歡了,畢竟 XML 才是真正的結構化標記語言,用於進行數據傳遞。
- 而如果不知道 JSON 的結構而去解析 JSON 的話,那簡直是噩夢。費時費力不說,代碼也會變得冗余拖沓,得到的結果也不盡人意。但是這樣也不影響眾多前台開發人員選擇 JSON。因為 json.js 中的 toJSONString() 就可以看到 JSON 的字符串結構。當然不是使用這個字符串,這樣仍舊是噩夢。常用 JSON 的人看到這個字符串之后,就對 JSON 的結構很明了了,就更容易的操作 JSON。
-
以上是在 Javascript 中僅對於數據傳遞的 XML 與 JSON 的解析。在 Javascript 地盤內,JSON 畢竟是主場作戰,其優勢當然要遠遠優越於 XML。如果 JSON 中存儲 Javascript 復合對象,而且不知道其結構的話,我相信很多程序員也一樣是哭着解析 JSON 的。
-
除了上述之外,JSON 和 XML 還有另外一個很大的區別在於有效數據率。JSON 作為數據包格式傳輸的時候具有更高的效率,這是因為 JSON 不像 XML 那樣需要有嚴格的閉合標簽,這就讓有效數據量與總數據包比大大提升,從而減少同等數據流量的情況下,網絡的傳輸壓力 。
-
1.8 iOS JSON 解析第三方框架
-
JSON 解析常用的第三方框架有:JSONKit、SBJson、TouchJSON,其性從左到右依次降低。
-
JSONKit 已經在 2012 年停止更新,官方說 JSONKit 比蘋果原生的 NSJSONSerialization 解析速度快,實測其實蘋果原生的 NSJSONSerialization 解析速度更快。
-
由於 NSJSONSerialization 在 iOS 5.0 之后才出現,NSJSONSerialization 適用於 iOS 5.0+ 版本的 iOS 開發。JSONKit 框架適用於 iOS 4.0 及以前版本的 iOS 開發。
2、系統方式 JSON 數據解析
-
Objective-C
-
解析 json 數據
/* 反序列化:將從服務器接收到的二進制數據轉換成 NSDictionary / NSArray 的過程,簡化程序開發,便於后續的字典轉模型。 數據必須符合 json 格式,用來接收的容器必須和 json 的最外層保持一致。 NSJSONReadingMutableContainers = (1UL << 0), // 容器可變,NSMutableDictionary 或 NSMutableArray。 NSJSONReadingMutableLeaves = (1UL << 1), // 葉子可變,返回的 JSON 對象中字符串的值為 NSMutableString。 NSJSONReadingAllowFragments = (1UL << 2) // 允許 JSON 字符串最外層既不是 NSArray 也不是 NSDictionary, 但必須是有效的 JSON 片段 反序列化中的可變不可變,實際用處不大,后續緊接着就是字典轉模型。因此輸入 0 效率最好。如果今后看到 ** 類型的參數, 又不想獲取對應的內容,傳遞 NULL 即可。傳入 nil 不會抱錯。 */ // 從本地文件中讀取數據 NSData *jsonData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"JsonDataFile" ofType:@"txt"]]; // 解析 json 數據 id result = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:NULL];
-
生成 json 數據
/* 序列化:將字典或者數組發送給服務器之前,轉換成二進制數據,方便網絡傳輸。 生成 json 數據的對象必須滿足以下條件: 對象最外層必須是 NSArray 或者 NSDictionary。 容器內的所有數據必須是 NSString, NSNumber, NSArray, NSDictionary, 或者 NSNull 類型。 字典的所有 key 都是 NSString 格式。 NSNumber 不能是 NaN(非數值) 或者 infinity(無限大)。 NSJSONWritingOptions: NSJSONWritingPrettyPrinted = (1UL << 0) 漂亮的格式打印 使用 0 時,生成的數據格式如下,將 JSON 數據發送給服務器時可以使用該種格式。 {"age":8,"score":99,"add":"beijing","name":"xiaoxin"} 使用 1 時,生成的數據格式如下,將 JSON 數據保存到本地時可以使用該種格式。 { "age" : 8, "score" : 99, "add" : "beijing", "name" : "xiaoxin" } */ // Foundation object NSDictionary *dicitionary = @{@"name":@"xiaoxin", @"age":@8, @"score":@99, @"add":@"beijing"}; // 判斷 Foundation 對象是否可以生成 json 數據 BOOL isValid = [NSJSONSerialization isValidJSONObject:dicitionary]; // 生成 json 數據 NSData *jData = [NSJSONSerialization dataWithJSONObject:dicitionary options:0 error:NULL];
-
-
Swift
-
解析 json 數據
/* 反序列化:將從服務器接收到的二進制數據轉換成 NSDictionary / NSArray 的過程,簡化程序開發,便於后續的字典轉模型。 數據必須符合 json 格式,用來接收的容器必須和 json 的最外層保持一致。 MutableContainers // 容器可變,NSMutableDictionary 或 NSMutableArray。 MutableLeaves // 葉子可變,返回的 JSON 對象中字符串的值為 NSMutableString。 AllowFragments // 允許 JSON 字符串最外層既不是 NSArray 也不是 NSDictionary,但必須是有效的 JSON 片段 反序列化中的可變不可變,實際用處不大,后續緊接着就是字典轉模型。因此輸入 0 效率最好。如果今后看到 ** 類型的參數, 又不想獲取對應的內容,傳遞 NULL 即可。傳入 nil 不會抱錯。 */ // 解析 json 數據 let jsonDataDic: AnyObject? = try? NSJSONSerialization.JSONObjectWithData(jsonData!, options: .MutableContainers)
-
生成 json 數據
/* 序列化:將字典或者數組發送給服務器之前,轉換成二進制數據,方便網絡傳輸。 生成 json 數據的對象必須滿足以下條件: 對象最外層必須是 NSArray 或者 NSDictionary。 容器內的所有數據必須是 NSString, NSNumber, NSArray, NSDictionary, 或者 NSNull 類型。 字典的所有 key 都是 NSString 格式。 NSNumber 不能是 NaN(非數值) 或者 infinity(無限大)。 */ // Foundation object let dicitionary:[String:AnyObject] = ["name":"xiaoxin", "age":8, "score":99, "add":"beijing"] // 判斷 Foundation 對象是否可以生成 json 數據 let isValid:Bool = NSJSONSerialization.isValidJSONObject(dicitionary) // 生成 json 數據 let jData:NSData? = try? NSJSONSerialization.dataWithJSONObject(dicitionary, options: .PrettyPrinted)
-
3、JSONKit 方式 JSON 數據解析
3.1 添加 JSONKit
-
GitHub 網址:https://github.com/johnezang/JSONKit
-
JSONKit 使用 MRC
-
Objective-C
// 添加第三方庫文件 JSONKit // 在 TARGETS -> Build Phases -> Compile Sources -> ...in .../JSONKit 后添加 -fno-objc-arc // 包含頭文件 #import "JSONKit.h"
-
Swift
// 添加第三方庫文件 JSONKit // 在 TARGETS -> Build Phases -> Compile Sources -> ...in .../JSONKit 后添加 -fno-objc-arc // 創建名為 “項目名-Bridging-Header.h” 的橋接頭文件,如: SwiftJSON-Bridging-Header.h // 在 TARGETS -> Build Setting -> Swift Compiler - Code generation -> Objective-C Bridging Header 中 // 添加 “項目名/項目名-Bridging-Header.h” 路徑,如: SwiftJSON/SwiftJSON-Bridging-Header.h // 在創建的橋接頭文件中包含頭文件 #import "JSONKit.h"
3.2 JSONKit 數據解析
-
Objective-C
-
JSONDecoder 方式解析
// 從本地文件中讀取數據 NSData *jsonData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"JsonDataFile" ofType:@"txt"]]; id result = [[JSONDecoder decoder] objectWithData:jsonData]; NSLog(@"%@ %@", result, [result class]);
-
JSONString 解析
// 單層 JSONString 解析 /* 如果 json 是 “單層” 的,即 value 都是字符串、數字,可以使用 objectFromJSONString */ // 單層 JSONString 數據 NSString *jsonStr1 = @"{\"a\":123, \"b\":\"abc\"}"; // 返回可變結果使用 mutableObjectFromJSONString 方法 NSDictionary *jsonStrDic1 = [jsonStr1 objectFromJSONString]; // 嵌套 JSONString 解析 /* 如果 json 有嵌套,即 value 里有 array、object,如果再使用 objectFromJSONString,程序可能會報錯, 測試結果表明:使用由網絡或得到的 php/json_encode 生成的 json 時會報錯,但使用 NSString 定義的 json 字符串時, 解析成功,最好使用 objectFromJSONStringWithParseOptions: */ // 嵌套 JSONString 數據 NSString *jsonStr2 = @"{\"a\":123, \"b\":\"abc\", \"c\":[456, \"hello\"], \"d\":{\"name\":\"張三\", \"age\":\"32\"}}"; // 返回可變結果使用 mutableObjectFromJSONStringWithParseOptions 方法 NSDictionary *jsonStrDic2 = [jsonStr2 objectFromJSONStringWithParseOptions:JKParseOptionLooseUnicode];
-
JSONData 解析
// 單層 JSONData 解析 NSData *jsonData1 = [@"{\"a\":123, \"b\":\"abc\"}" dataUsingEncoding:NSUTF8StringEncoding]; // 返回可變結果使用 mutableObjectFromJSONData 方法 NSDictionary *jsonDataDic1 = [jsonData1 objectFromJSONData]; // 嵌套 JSONData 解析 // 從本地文件中讀取數據 NSData *jsonData2 = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"JsonDataFile" ofType:@"txt"]]; // 返回可變結果使用 mutableObjectFromJSONStringWithParseOptions 方法 NSDictionary *jsonDataDic2 = [jsonData2 objectFromJSONDataWithParseOptions:JKParseOptionLooseUnicode];
-
生成 JSONString 數據
// NSString -> JSONString NSString *str1 = @"{a\":123, \"b\":\"abc\"}"; // 默認參數為 JKSerializeOptionNone,includeQuotes 為 YES NSString *jsonStrFromStr1 = [str1 JSONString]; // includeQuotes 為 NO 時,編碼后的數據最外層不含引號 NSString *jsonStrFromStr2 = [str1 JSONStringWithOptions:JKSerializeOptionNone includeQuotes:NO error:nil]; // NSArray/NSDictionary -> JSONString NSDictionary *dic1 = @{@"name":@"xiaoxin", @"age":@8, @"Info":@{@"score":@99, @"add":@"beijing"}}; // 默認參數為 JKSerializeOptionNone NSString *jsonStrFromDic1 = [dic1 JSONString]; NSString *jsonStrFromDic2 = [dic1 JSONStringWithOptions:JKSerializeOptionEscapeUnicode error:nil];
-
生成 JSONData 數據
// NSString -> JSONData NSString *str2 = @"{a\":123, \"b\":\"abc\"}"; // 默認參數為 JKSerializeOptionNone,includeQuotes 為 YES NSData *jsonDataFromStr1 = [str2 JSONData]; NSData *jsonDataFromStr2 = [str2 JSONDataWithOptions:JKSerializeOptionNone includeQuotes:NO error:nil]; // NSArray/NSDictionary -> JSONData NSDictionary *dic2 = @{@"name":@"xiaoxin", @"age":@8, @"Info":@{@"score":@99, @"add":@"beijing"}}; // 默認參數為 JKSerializeOptionNone NSData *jsonDataFromDic1 = [dic2 JSONData]; NSData *jsonDataFromDic2 = [dic2 JSONDataWithOptions:JKSerializeOptionEscapeUnicode error:nil];
-
-
Swift
-
JSONDecoder 方式解析
// 從本地文件中讀取數據 let jsonData:NSData = NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("JsonDataFile", ofType: "txt")!)! let result:AnyObject = JSONDecoder.decoder().objectWithData(jsonData) print(result);
-
JSONString 解析
// 單層 JSONString 解析 /* 如果 json 是 “單層” 的,即 value 都是字符串、數字,可以使用 objectFromJSONString */ // 單層 JSONString 數據 let jsonStr1:String = "{\"a\":123, \"b\":\"abc\"}" // 返回可變結果使用 mutableObjectFromJSONString 方法 let jsonStrDic1:AnyObject = jsonStr1.objectFromJSONString() // 嵌套 JSONString 解析 /* 如果 json 有嵌套,即 value 里有 array、object,如果再使用 objectFromJSONString,程序可能會報錯, 測試結果表明:使用由網絡或得到的 php/json_encode 生成的 json 時會報錯,但使用NSString 定義的 json 字符串時, 解析成功,最好使用 objectFromJSONStringWithParseOptions: */ // 嵌套 JSONString 數據 let jsonStr2:String = "{\"a\":123, \"b\":\"abc\", \"c\":[456, \"hello\"], \"d\":{\"name\":\"張三\", \"age\":\"32\"}}" // 返回可變結果使用 mutableObjectFromJSONStringWithParseOptions 方法 let jsonStrDic2:AnyObject = jsonStr2.objectFromJSONStringWithParseOptions(UInt(JKParseOptionLooseUnicode))
-
JSONData 解析
// 單層 JSONData 解析 let jsonData1:NSData = "{\"a\":123, \"b\":\"abc\"}".dataUsingEncoding(NSUTF8StringEncoding)! // 返回可變結果使用 mutableObjectFromJSONData 方法 let jsonDataDic1:AnyObject = jsonData1.objectFromJSONData() // 嵌套 JSONData 解析 // 從本地文件中讀取數據 let jsonData2:NSData = NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("JsonDataFile", ofType: "txt")!)! // 返回可變結果使用 mutableObjectFromJSONDataWithParseOptions 方法 let jsonDataDic2:AnyObject = jsonData2.objectFromJSONDataWithParseOptions(UInt(JKParseOptionLooseUnicode))
-
生成 JSONString 數據
// String -> JSONString let str1:String = "{a\":123, \"b\":\"abc\"}" // 默認參數為 JKSerializeOptionNone,includeQuotes 為 YES let jsonStrFromStr1:String = str1.JSONString() // includeQuotes 為 NO 時,編碼后的數據最外層不含引號 let jsonStrFromStr2:String = try! str1.JSONStringWithOptions(UInt(JKSerializeOptionNone), includeQuotes:false) // NSArray/NSDictionary -> JSONString let dic1:NSDictionary = ["name":"xiaoxin", "age":8, "Info":["score":99, "add":"beijing"]] // 默認參數為 JKSerializeOptionNone let jsonStrFromDic1:String = dic1.JSONString() let jsonStrFromDic2:String = try! dic1.JSONStringWithOptions(UInt(JKSerializeOptionEscapeUnicode))
-
生成 JSONData 數據
// String -> JSONData let str2:String = "{a\":123, \"b\":\"abc\"}" // 默認參數為 JKSerializeOptionNone,includeQuotes 為 YES let jsonDataFromStr1:NSData = str2.JSONData() // includeQuotes 為 NO 時,編碼后的數據最外層不含引號 let jsonDataFromStr2:NSData = try! str2.JSONDataWithOptions(UInt(JKSerializeOptionNone), includeQuotes:false) // NSArray/NSDictionary -> JSONData let dic2:NSDictionary = ["name":"xiaoxin", "age":8, "Info":["score":99, "add":"beijing"]] // 默認參數為 JKSerializeOptionNone let jsonDataFromDic1:NSData = dic2.JSONData() let jsonDataFromDic2:NSData = try! dic2.JSONDataWithOptions(UInt(JKSerializeOptionEscapeUnicode))
-
4、JSONKit 與 NSJSONSerialization 對比測試
static int largeNumber = 100 * 1000;
// JSONKit 解析
NSData *jsonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://192.168.88.200/demo.json"]];
NSLog(@"JSONKit start");
CFAbsoluteTime start1 = CFAbsoluteTimeGetCurrent();
for (int i = 0; i < largeNumber; ++i) {
[[JSONDecoder decoder] objectWithData:jsonData];
}
NSLog(@"JSONKit end: %f \n", CFAbsoluteTimeGetCurrent() - start1);
// NSJSONSerialization 解析
NSData *jsonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://192.168.88.200/demo.json"]];
NSLog(@"NSJSONSerialization start");
CFAbsoluteTime start2 = CFAbsoluteTimeGetCurrent();
for (int i = 0; i < largeNumber; ++i) {
[NSJSONSerialization JSONObjectWithData:jsonData options:0 error:NULL];
}
NSLog(@"NSJSONSerialization end: %f", CFAbsoluteTimeGetCurrent() - start2);