iOS - JSON 数据解析
前言
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 那样需要有严格的闭合标签,这就让有效数据量与总数据包比大大提升,从而减少同等数据流量的情况下,网络的传输压力 。
- 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);
iOS - JSON 数据解析的更多相关文章
- IOS - JSON数据解析 小3种方法
[manager GET:serverURL parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject ...
- iOS开发笔记3:XML/JSON数据解析
这篇主要总结在iOS开发中XML/JSON数据解析过程用到的方法.XML数据解析主要使用SAX方式的NSXMLParser以及DOM方式的GDataXML,JSON数据解析主要使用NSJSONSeri ...
- iOS学习—JSON数据解析
关于在iOS平台上进行JSON解析,已经有很多第三方的开源项目,比如TouchJson,JSONKit,SBJon等,自从iOS5.0以后,苹果SDK推出了自带的JSON解决方案NSJSONSer ...
- iOS学习——JSON数据解析(十一)
在之前的<iOS学习——xml数据解析(九)>介绍了xml数据解析,这一篇简单介绍一下Json数据解析.JSON 即 JavaScript Object Natation,它是一种轻量级的 ...
- iOS学习笔记(十一)——JSON数据解析
在之前的<iOS学习——xml数据解析(九)>介绍了xml数据解析,这一篇简单介绍一下Json数据解析.JSON 即 JavaScript Object Natation,它是一种轻量级的 ...
- 浅议iOS网络数据解析
/*------------------------------------ 数据解析: 1.JSON数据 --------------------------------*/ 重点:1.什么是JSO ...
- [开源 .NET 跨平台 数据采集 爬虫框架: DotnetSpider] [四] JSON数据解析
[DotnetSpider 系列目录] 一.初衷与架构设计 二.基本使用 三.配置式爬虫 四.JSON数据解析与配置系统 场景模拟 假设由于漏存JD SKU对应的店铺信息.这时我们需要重新完全采集所有 ...
- JSON数据解析 基础知识及链接收集
JSON数据解析学习 JSON介绍 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式. JSON 是存储和交换文本信息的语法.类似 XML.但是JSON 比 ...
- 浅谈JSON数据解析方法
JSON数据解析 JSON是什么?? 如何把JSON数据解析出来 如何把一个字典转换为JSON JSON详细介绍 JSON(JavaScript Object Notation) 是一种轻量级的数据交 ...
随机推荐
- 网络模拟器WANem使用配置图文教程
转自:http://blog.csdn.net/zm_21/article/details/25810263 WANem简介 由于公司在一些场合需要模拟真实的网络环境,如时延,丢包,抖动等,虽然使用L ...
- zzy:java采用的是16位的Unicode字符集作为编码方式------理解
java语言使用16位的Unicode字符集作为编码方式,是疯狂Java中的原话. 1,编码方式只是针对字符类型的(不包括字符串类,数值类型int等,这些只是在解释[执行]的时候放到Jvm的不同内存块 ...
- C语言中如何将二维数组作为函数的参数传递
今天写程序的时候要用到二维数组作参数传给一个函数,我发现将二维数组作参数进行传递还不是想象得那么简单里,但是最后我也解决了遇到的问题,所以这篇文章主要介绍如何处理二维数组当作参数传递的情况,希望大家不 ...
- Android开发如何去除标题栏title(转)
去除标题栏title其实非常简单,他有两种方法,一种是在代码中添加,另一种是在AndroidManifest.xml中添加: 1.在代码中实现:在此方法setContentView(R.layout. ...
- 【criteria CascadeType】级联的不同情况
使用criteria进行增删改查操作,可能会发生级联删除的情况,例如对员工表进行删除,可能会级联删除掉部门表中的某一条信息[类似这样的情况] 对此,我们可以在实体类中对级联的关系进行管理: 对于cri ...
- user_jj两条记录改成一条
1.前台index控制器,用user_jj.*add找到,home_ddxx_pcz_cl() 2.前台index控制器,用user_jj.*add找到,tgbz_list_sd_cl(),tgbz_ ...
- TweenMax参数补充
构造函数:TweenMax(target:Object, duration:Number, vars:Object) target:Object -- 需要缓动的对象 duration:Number ...
- 2016.9.1 JavaScript入门之五
1.数据类型:对象:也可以被认为是一个键/值存储,像一个字典.可以取代switch{case:case:}或者if else 例如: function phoneticLookup(val) { va ...
- DSP using MATLAB 示例 Example3.10
用到的性质 上代码: n = -5:10; x = rand(1,length(n)) + j * rand(1,length(n)); k = -100:100; w = (pi/100)*k; % ...
- node.js整理 03文件操作-遍历目录和文本编码
遍历目录 递归算法 遍历目录时一般使用递归算法,否则就难以编写出简洁的代码. 递归算法与数学归纳法类似,通过不断缩小问题的规模来解决问题 function factorial(n) { if (n = ...