JSONKit 同时由 BSD 许可和 Apache 许可 v2.0 许可。
版权所有 © 2011, John Engelhart。
更新: (2011/12/18) 下面的基准测试是在 Apples NSJSONSerialization
可用之前完成的(截至 Mac OS X 10.7 和 iOS 5)。显然的问题是:哪个更快,NSJSONSerialization
还是 JSONKit?据 这个网站 报告,JSONKit 比该快。根据记录的数字进行的“快速草稿”计算表明,JSONKit 比该快约 25% 到 40%,这是一个相当大的改进。
解析 | 序列化 |
---|---|
比二进制 .plist 快 23%! |
比二进制 .plist 快 549%! |
gcc-4.2 -DNS_BLOCK_ASSERTIONS -O3 -arch x86_64
。getrusage
报告的用户 + 系统时间。twitter_public_timeline.json
的 samsoffes/json-benchmarks。.plist
格式不支持序列化 NSNull
,因此将原始 JSON 中的 null
值更改为 "null"
。libz.dylib
链接到 libz.dylib
- 不需要在编译时手动链接。gzip
签名标题,解析 / 反序列化会自动解压。JKSerializeOptionCompress
传递给 -JSONDataWithOptions:error:
来压缩 / gzip
序列化的 JSON。JSON对比PLIST,最终的较量 对常用的JSON库进行了基准测试,并将它们与苹果的.plist
格式进行了比较。
JavaScript对象表示法,或称JSON,是一种轻量级的基于文本的序列化格式,用于结构化数据,被许多基于Web的服务和API使用。它由RFC 4627定义。
JSON提供了以下基本类型
null
true
和false
这些基本类型映射到以下Objective-C框架类
JSON | Objective-C |
---|---|
null |
NSNull |
true 和false |
NSNumber |
数字 | NSNumber |
字符串 | NSString |
数组 | NSArray |
Object | NSDictionary |
JSONKit内部使用Core Foundation,并假设对于每个等效的基本类型,Core Foundation =Foundation,即 CFString
≡ NSString
。
本文件中“必须”、“禁止”、“必要”、“应当”、“不应”、“应该”,“推荐”、“可以”和“可选”等关键字应按RFC 2119中的描述进行解释。
关于Unicode的细节和需求,《JSON规范》略显模糊,并且它没有规定如何处理Unicode问题和错误。大多数的模糊性来源于对RFC 4627第3节“编码”的解释和范围:JSON文本应使用Unicode进行编码。
作者的意见和解释是,《RFC 4627》要求JSON实现必须遵循《Unicode标准》中规定的要求,尤其是在《Unicode标准的第Conformance
章节中,规定了与处理、解释和操作Unicode文本相关的要求。
JSONKit的默认行为是严格遵守RFC 4627。作者的意见和解释是,《RFC 4627》要求JSON应以Unicode进行编码,因此不符合《Unicode标准》中定义的有效Unicode的JSON是无效的JSON。因此,JSONKit不会接受包含无效Unicode的JSON。默认的严格行为意味着没有启用JKParseOptionLooseUnicode
选项。
当启用JKParseOptionLooseUnicode
选项时,JSONKit遵循Unicode 6.0标准,第三章-一致性中给出的规范和建议,特别是3.9节“Unicode编码形式”。作为一个一般规则,任何遇到的无效Unicode都将用Unicode代码点U+FFFD
替换。JSONKit试图遵循推荐的使用U+FFFD的最佳实践:将无效子序列的最大部分替换为单个U+FFFD。
以下Unicode代码点被视为无效Unicode,如果启用JKParseOptionLooseUnicode
选项,将用U+FFFD
替换
U+0000
.
U+D800
到 U+DFFF
, inclusively。
U+FDD0
到 U+FDEF
, inclusively。
U+nFFFE
和 U+nFFFF
,其中 n 是从 0x0
到 0x10
代码点 U+FDD0
到 U+FDEF
、U+nFFFE
和 U+nFFFF
(其中 n 是从 0x0
到 0x10
)被Unicode标准定义为“非字符”,不应相互交换。
User+0000是合法的Unicode编码点,对它不做异常处理。这是因为在字符串处理代码中,这个特定的编码点被用于指定字符串的结尾。任何这样的字符串处理代码都可能在User+0000出现的地方错误地停止字符串的处理。虽然在这一点上,合理人可能会有不同的意见,但作者认为允许包含User+0000的JSON字符串带来的风险大于其带来的好处。在字符串中允许User+0000未修改地出现的一个风险是它可能会通过微妙地改变字符串的语义,从而有能力被恶意的攻击者利用。这与从Unicode文本中任意删除字符的问题相似。
RFC 4627 在第4节“解析器”中允许这样的限制:实现可以设置字符串的长度和字符内容限制。
虽然Unicode标准允许对原始JSON进行修改(用User+FFFD替换非法Unicode),但RFC 4627 对此问题没有明确说明。作者的观点和解释是,RFC 4627第3节《编码》中的JSON文本应使用Unicode编码
暗示了这种修改不仅允许,而且任何严格遵循RFC 4627的JSON实现都必须预期这种修改。作者感到有必要指出,这种观点和解释可能不被他人分享,实际上可能是少数意见和解释。你应该意识到,任何对原始JSON的修改可能会细微地改变其语义,因此可能对其消费最终结果的相关内容有安全相关的含义。
重要的是要注意,JSONKit不会删除正在解析的JSON中的字符,因为这是Unicode标准中指定的一项要求。更多信息可以在Unicode安全FAQ和Unicode技术报告第36号——Unicode安全考虑中找到,特别是非可视化安全问题部分。
JSON规范并没有指定JSON字符串值的详细要求,除了这些字符串必须由Unicode编码点组成,也没有指定如何处理错误。虽然JSONKit会尽力(在上述有关Unicode的合理警告范围内)准确地保留解析的JSON字符串,但它无法保证NSString
将保留原始JSON字符串的准确Unicode语义。
JSONKit在对解析后的JSON字符串进行操作时不会进行任何Unicode规范化,但不能保证使用NSString
类来实例化JSON字符串使用功能时,不会对解析后使用的JSON字符串进行Unicode规范化。该NSString
类可能会添加额外的限制或者以某种方式将JSON字符串转换,使得JSON字符串与实例化的NSString
对象不是一一对应的。换句话说,JSONKit不能保证当你将一个JSON字符串转换成一个NSString
对象然后再转换回JSON字符串,这两个JSON字符串将完全相同,尽管在实际情况中它们确实如此。"完全相同"在这种情况下意味着位对位相同。JSONKit甚至不能保证两个JSON字符串将是Unicode等效的,尽管在实际情况中它们将是,并且这是两个来回转换的JSON字符串不再位对位相同最可能的原因。
JSONKit将true
和false
映射到CFBoolean
值kCFBooleanTrue
和kCFBooleanFalse
。从概念上讲,可以将CFBoolean
值视为并作为NSNumber
类的对象来处理。使用CFBoolean
的好处是,true
和false
的JSON值可以在不进行转换或提升到值分别为0
或1
的NSNumber
的情况下进行循环序列化和反序列化。
JSON规范未指定JSON数值的细节或要求,也未指定应如何处理转换错误。通常,JSONKit不会接受含有它无法无误或无精度损失转换的JSON数值的JSON。
对于非浮点数(即不包括.
或e|E
的JSON数值),无论目标架构是32位还是64位,JSONKit都使用内部64位C原始类型。对于无符号值(即不以-
开始的值),这允许值为264-1
,而对于负值,最多可达-263
。作为一个特例,JSON数值-0
被视为浮点数,因为底层浮点原始类型能够表示负零,而底层的补码非浮点原始类型不能。超出这些限制的包含数值的JSON将失败解析,可选择返回一个NSError
对象。使用strtoll()
和strtoull()
函数进行这些转换。
C语言中的double
基本类型,或IEEE 754双精度64位浮点格式,用于表示浮点JSON数值。包含无法表示为double
数值的浮点数(例如,由于溢出或下溢)的JSON将解析失败,并且可以选择性地返回一个NSError
对象。使用strtod()
函数进行转换。请注意,JSON标准不允许无限大或NaN
(不是数值)。浮点值的转换和处理并不简单。不幸的是,RFC 4627对此类细节处理保持沉默。不应该依赖或期望被循环转换的浮点值将具有相同的文本表示或甚至相等的比较。即使JSONKit被用作解析器和JSON的创建者,这也同样如此,更不用说在不同系统和实现之间传输JSON了。
对于JSON对象(或JSONKit术语中的NSDictionary
),RFC 4627规定“对象内名称应唯一”(注意:name
在JSONKit术语中是key
)。目前,对于包含对象中不唯一名称的JSON,JSONKit的行为是未定义的。然而,JSONKit目前试图遵循“选择最后解析的键/值对”政策。这项行为尚未最终确定,不应依赖。
之前关于JSON字符串的限制对于JSON对象很重要,因为JSON字符串用作key
。JSON规范没有指定用于JSON对象中的keys
的JSON字符串的细节或要求,特别是两个keys
比较相等的含义。不幸的是,由于RFC 4627声明“JSON文本必须使用Unicode编码”,这意味着必须使用Unicode标准来解释JSON,并且Unicode标准允许使用不同Unicode代码点编码的字符串“比较相等”。JSONKit专门使用NSString
来管理解析后的JSON字符串。因为NSString
使用Unicode作为其基础,因此存在将原始JSON字符串中包含的Unicode代码点微弱且默默地转换为Unicode等效字符串的可能性。因此,对于在JSON对象中用作keys
的JSON字符串,如果这些字符串在Unicode等效但不二进制等效的情况下,JSONKit的行为是未定义的。
在序列化时,顶层容器以及所有子元素在枚举过程中必须保持严格的不变性。这个属性用于进行某些优化,例如,如果一个特定的对象已经被序列化,可以重用之前序列化的UTF8
字符串的结果(即,可以直接复制先前序列化的UTF8
字符串,而不是再次执行所有序列化工作)。虽然这也许只对那些使用或继承自JSONKit序列化类的运行时或自定义类进行极其不同寻常操作的人感兴趣(即,每次请求其值进行序列化时,值都会发生变化的自定义对象),但它也涵盖了在枚举过程中任何要序列化的对象被修改的情况(即,由另一个线程进行修改)。JSONKit请求对象值次数是不确定的,最少一次,最多可达它在序列化JSON中出现的次数——因此,对象每次出现在序列化输出中时,都不能依赖于接收到请求其值的消息。如果违反这些要求,行为是未定义的。
要序列化的对象必须是循环的。如果要序列化的对象包含循环引用,行为是未定义的。例如,…将导致未定义行为。
[arrayOne addObject:arrayTwo];
[arrayTwo addObject:arrayOne];
id json = [arrayOne JSONString];
…将导致未定义行为。
NSString
对象的内部内容被编码为UTF8
并添加到序列化的JSON中。JSONKit假设NSString
生产格式良好的UTF8
Unicode,并且不进行额外的转换验证。当启用JKSerializeOptionEscapeUnicode
时,JSONKit将使用\uXXXX
将作为单个UTF16
代码单元编码的Unicode代码点编码,并将需要UTF16
代理对的Unicode代码点编码为\uhigh\ulow
。虽然JSONKit尽力准确序列化NSString
对象的内部内容,但要符合RFC 4627的要求,NSString
类使用Unicode标准来表示字符串。你应该知道,Unicode标准按照以下方式定义字符串等价性:比较相等的字符串不必是位对位的相同。因此,可能存在NSString
可能以使其成为Unicode等价的方式进行字符串的修改,但与原始字符串不是位对位的相同的可能性。
NSDictionary
类允许使用任何对象作为key
,而JSON只允许使用字符串作为keys
。因此,如果JSONKit在序列化过程中遇到包含非NSString
对象键的NSDictionary
,则会出错。更具体地说,键必须返回YES
,当发送-isKindOfClass:
如果JSONKit在序列化过程中遇到非NSNull
、NSNumber
、NSString
、NSArray
或NSDictionary
类的对象时,将会报错。更具体地说,如果遇到的对象中,上述所有类的-isKindOfClass:
方法都返回NO
,JSONKit将报错。
JSON不允许Numbers为±Infinity
或±NaN
。因此,如果JSONKit在序列化过程中遇到包含这些值的NSNumber
对象,将报错。
使用[NSNumber numberWithBool:YES]
和[NSNumber numberWithBool:NO]
创建的对象将分别映射到JSON值true
和false
。具体来说,一个对象必须与kCFBooleanTrue
或kCFBooleanFalse
有指针相等性(即 if((id)object == (id)kCFBooleanTrue)
),才能映射到JSON值true
和false
。
不是布尔值的NSNumber
对象将被发送到-objCType
来确定其表示的C原始数据类型。那些响应类型为cislq
集合的对象被视为long long
类型,响应类型为CISLQB
集合的对象被视为unsigned long long
类型,响应类型为fd
集合的对象被视为double
类型。响应类型不在所提及类型集合中的NSNumber
对象将导致JSONKit报错。
更具体地说,使用CFNumberGetValue(object, kCFNumberLongLongType, &longLong)
来检索有符号和无符号的整数值,并使用-objCType
方法报告的类型来确定结果是带符号的还是无符号的。对于浮点值,使用CFNumberGetValue
,并使用kCFNumberDoubleType
作为类型参数来检索值。
浮点数使用printf
格式转换说明符%.17g
转换为它们的十进制表示形式。理论上,这允许表示至多等效于float
或IEEE 754 单精度 32 位浮点的精度。这意味着,在实用层面,double
值转换为float
值时会有精度损失。RFC 4627标准对此如何处理浮点数没有明确规定,作者发现现实世界中的JSON实现在这方面差异很大。此外,%g
格式转换说明符可能会将能够精确表示为整数的浮点值转换为不包含.
或e
的文本表示形式——基本上是将浮点值无声地提升为整数值(例如,5.0
变为5
)。由于这些问题以及许多其他关于浮点值转换和处理问题,您不应期望或依赖于浮点值保持其全部精度,或者当进行反向转换时,进行比较。
请使用github.com JSONKit问题追踪器来报告错误。
作者请求您不要在没有先手动验证它确实是JSONKit的真实施问题时提交JSONKit的错误报告,如果合适,这不是由C99语言规范定义的“合法”C代码。如果clang
静态分析器报告的是JSONKit中不是实际问题且是合法代码(根据C99语言规范定义),那么提交错误报告或投诉的适当地方是clang
静态分析器开发者。
JSONKit不是为了与Mac OS X垃圾回收一起使用设计的。当使用-fobjc-gc
编译JSONKit时,其行为是“未定义”的。Mac OS X垃圾回收可能永远不会被支持,这种情况极不可能发生。
JSONKit不是设计用来与Objective-C自动引用计数(ARC)一起使用的。使用-fobjc-arc
编译时的行为是“未定义”的。没有使用ARC编译的JSONKit与使用ARC编译的代码混合在一起的行为规范上是“未定义”的,因为当时尚未进行分析以确认这种配置是否安全使用。目前,没有计划在JSONKit中支持ARC。尽管是暂定的,但由于与Mac OS X垃圾回收不支持相同的原因,ARC很可能永远不会被支持。
要由JSONKit解析的JSON必须是Unicode编码。在非常不可能的情况下,如果您得到未使用Unicode编码的JSON,您必须先将JSON转换为Unicode,最好是作为UTF8
。完成这一目标的办法之一是使用NSString
方法-initWithBytes:length:encoding:
和-initWithData:encoding:
。
内部,低级解析引擎只使用UTF8
。JSONDecoder
方法-objectWithData:
接收一个NSData
对象作为参数,假设这个NSData
对象的原始字节是UTF8
编码的,否则行为是未定义
。
同时使用多个线程中的同一个实例化的JSONDecoder
对象是不安全的。如果您希望在不同线程之间共享JSONDecoder
,您应当负责添加互斥锁(mutex)以确保一次只有一个线程使用共享的JSONDecoder
对象来解析JSON。
启用NS_BLOCK_ASSERTIONS
预处理器标记。JSONKit内部大量使用NSCParameterAssert()
以确保各种参数、变量和其他状态只包含合法和预期的值。如果断言检查失败,将导致运行时异常,这通常会导致程序终止。这些检查和断言是有代价的:它们需要时间来执行,并且不贡献于实际工作。启用NS_BLOCK_ASSERTIONS
是完全安全的,因为JSONKit总是执行对正确操作所必需的检查。使用NSCParameterAssert()
的检查是完全可选的,通常用于“调试”构建,其中通常会需要更多的完整性检查。尽管效果因机器而异,作者发现将-DNS_BLOCK_ASSERTIONS
添加到-O2
优化设置中通常可以大致提高7-12%的性能。
因为非常低级的解析引擎只与UTF8
字节流工作,所以任何尚未编码为UTF8
的内容必须先转换为UTF8
。虽然JSONKit为NSString
类提供了扩展,使您可以方便地将包含在NSString
中的JSON进行转换,但这种便利是有成本的。JSONKit必须分配一个足以下载数据的自动释放NSMutableData
,然后才能将字符串转换为UTF8
并开始解析。这需要时间和内存。解析完成后,JSONKit将自动释放的NSMutableData
长度设置为0
,这允许NSMutableData
释放内存。这有助于减少被使用但直到自动释放池弹出之前不可用的内存数量。因此,如果速度和内存使用是优先考虑的,理想情况下应避免使用NSString
方便的方法。
如果您从Web服务器接收JSON数据,并且能够确定Web服务器返回的原始字节是作为UTF8
编码的JSON,您应该使用JSONDecoder
的方法-objectWithUTF8String:length:
,这将立即开始解析这些指针的字节。在实践中,每个将JSON转换为Objective-C对象的JSONKit方法最终都会调用此方法来完成转换。
如果您正在使用《NSURL》类家族提供的各种方式之一来从网络服务器接收JSON结果,这些结果通常以NSData
对象的形式返回,并且您能够确定包含在《NSData》中的原始字节是编码为UTF8
,那么您应该使用JSONDecoder
方法的objectWithData:
或《NSData》方法的-objectFromJSONData
。如果您需要转换大量JSON,最好是一次性实例化一个JSONDecoder
对象,然后使用同一个实例进行所有转换。这有两个好处
-objectFromJSONData
创建一个自动释放的JSONDecoder
对象来完成一次性转换。通过一次性实例化一个JSONDecoder
对象,并重复使用objectWithData:
方法,您可以避免这种开销。平均而言,将《NSDictionary》或《NSArray》序列化为JSON时,JSONData…
方法比JSONString…
方法快近四倍。这种速度差异完全是由于《NSString》实例化开销。
如果可能的话,当处理JSON时,使用《NSData》而不是《NSString》方法。这可以避免《NSString》为了提供其内容的面向对象接口而执行的有时相当重要的转换开销。对于许多使用情况,确实不需要使用《NSString》,从而导致浪费努力—例如,使用JSONKit将《NSDictionary》或《NSArray》序列化为《NSString》。然后,这个《NSString》会传递给一个方法,该方法将JSON发送到网络服务器,这通常需要在发送之前将《NSString》转换为《NSData》。在这种情况下,直接将收集对象序列化为《NSData》可以避免不必要地在《NSString》对象之间进行转换。
objectWith…
方法返回不可变的收集对象,它们的相应mutableObjectWith…
方法返回可变的收集对象。
注意:在NSData
对象中包含的字节必须使用UTF8
编码。
重要:如果parseOptionFlags
不是有效的,则方法会抛出NSInvalidArgumentException
。
重要:如果string
是NULL
,则objectWithUTF8String:
和mutableObjectWithUTF8String:
会抛出NSInvalidArgumentException
。
重要:如果jsonData
是NULL
,则objectWithData:
和mutableObjectWithData:
会抛出NSInvalidArgumentException
。
+ (id)decoder;
+ (id)decoderWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
- (id)initWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
- (void)clearCache;
- (id)objectWithUTF8String:(const unsigned char *)string length:(size_t)length;
- (id)objectWithUTF8String:(const unsigned char *)string length:(size_t)length error:(NSError **)error;
- (id)mutableObjectWithUTF8String:(const unsigned char *)string length:(size_t)length;
- (id)mutableObjectWithUTF8String:(const unsigned char *)string length:(size_t)length error:(NSError **)error;
- (id)objectWithData:(NSData *)jsonData;
- (id)objectWithData:(NSData *)jsonData error:(NSError **)error;
- (id)mutableObjectWithData:(NSData *)jsonData;
- (id)mutableObjectWithData:(NSData *)jsonData error:(NSError **)error;
- (id)objectFromJSONString;
- (id)objectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
- (id)objectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
- (id)mutableObjectFromJSONString;
- (id)mutableObjectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
- (id)mutableObjectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
- (id)objectFromJSONData;
- (id)objectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
- (id)objectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
- (id)mutableObjectFromJSONData;
- (id)mutableObjectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
- (id)mutableObjectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
解析选项 | 描述 |
---|---|
JKParseOptionNone |
如果没有指定其他解析选项标记,这是默认值,并且是便捷方法未提供显式指定使用哪个解析选项的参数时使用的选项。与JKParseOptionStrict 同义。 |
JKParseOptionStrict |
JSON将严格按照RFC 4627规范进行解析。 |
JKParseOptionComments |
允许在JSON中使用C样式的// 和/* … */ 注释。这是JSON的相当常见的扩展,但包含C样式注释的JSON不是符合规范的JSON。 |
JKParseOptionUnicodeNewlines |
允许在JSON中使用Unicode推荐的(?:\r\n|[\n\v\f\r\x85\p{Zl}\p{Zp}]) 换行符。JSON规范只允许换行字符\r 和\n ,但此选项允许解析包含Unicode推荐换行符的JSON。包含这些额外换行符的JSON不是符合规范的JSON。 |
JKParseOptionLooseUnicode |
通常解码器会在任何不合法的Unicode处停止并返回错误。此选项允许解析带有不合法Unicode的JSON,而不会报告错误。任何不合法的Unicode将替换为\uFFFD 或REPLACEMENT CHARACTER ,正如Unicode 6.0标准,第三章中3.9节Unicode编码形式所指定的。 |
JKParseOptionPermitTextAfterValidJSON |
通常,跟随JSON的任何非空白字符将被解释为解析失败。此选项允许忽略任何尾随的非空白字符,并且不会导致解析错误。 |
序列化接口包括针对需要序列化单个NSString
的NSString
便捷方法。对于需要此功能的人,比将单个NSString
包装在NSArray
中然后从序列化的JSON结果中删除不必要的[
…]
字符更方便。在序列化单个NSString
时,您可以通过includeQuotes:
参数控制序列化后的JSON结果是否由引号包围。
示例 | 结果 | 参数 |
---|---|---|
a "test"... |
"a \"test\"..." |
includeQuotes:YES |
a "test"... |
a \"test\"... |
includeQuotes:否 |
注意: 不包含 includeQuotes:
参数的 NSString
方法,其行为等同于使用 includeQuotes:YES
调用。
注意: 返回的 NSData
对象中的字节是 UTF8
编码。
- (NSData *)JSONData;
- (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
- (NSString *)JSONString;
- (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
- (NSData *)JSONData;
- (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions includeQuotes:(BOOL)includeQuotes error:(NSError **)error;
- (NSString *)JSONString;
- (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions includeQuotes:(BOOL)includeQuotes error:(NSError **)error;
序列化选项 | 描述 |
---|---|
JKSerializeOptionNone |
这是默认选项,如果没有指定其他序列化选项标志,并且在便利方法没有提供参数来显式指定要使用的序列化选项时使用。 |
JKSerializeOptionPretty |
通常,序列化的 JSON 不会包含任何不必要的 white-space 。虽然这种形式是最紧凑的,但没有空白意味着它只可能被另一个 JSON 解析器所喜爱。启用此选项会导致 JSONKit 添加额外的 white-space ,使得人们更容易阅读。除了额外的 white-space 之外,序列化的 JSON 与没有启用此选项时生成的 JSON 完全相同。 |
JKSerializeOptionEscapeUnicode |
当 JSONKit 遇到 NSString 对象中的 Unicode 字符时,默认行为是将这些 Unicode 字符编码为 UTF8 。此选项会导致 JSONKit 将这些字符编码为 \uXXXX 。例如,["w∈L⟺y(∣y∣≤∣w∣)"] 变为 ["w\u2208L\u27fa\u2203y(\u2223y\u2223\u2264\u2223w\u2223)"]
|
JKSerializeOptionEscapeForwardSlashes |
根据 JSON 规范,/ (U+002F ) 字符可以被反斜杠转义(即 \/ ),但这不是必需的。JSONKit 的默认行为是 不会 反斜杠转义 / 字符。不幸的是,发现一些实际应用中的 ASP.NET 日期格式 需要将日期严格编码为 \/Date(|\)\/ ,而这只能通过使用 JKSerializeOptionEscapeForwardSlashes 来实现。更多信息请参阅 github issue #21。 |