SBJson库

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于JavaScript的一个子集。 JSON采用完全独立于语言的文本格式,数据交换容易。容易阅读和编写,同时也易于机器解析和生成

Json简单说就是javascript中的对象和数组,所以这两种结构就是对象和数组2种结构,通过这两种结构可以表示各种复杂的结构   

1、对象:对象在js中表示为“{}”扩起来的内容,数据结构为 {key:value,key:value,…}的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,所以很容易理 解,取值方法为 对象.key 获取属性值,这个属性值的类型可以是 数字、字符串、数组、对象几种。   

2、数组:数组在js中是中括号“[]”扩起来的内容,数据结构为 ["java","javascript","vb",...],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是 数字、字符串、数组、对象几种。

在ISO开发中有很多第三方类库支持Json解析,这里介绍一下SBJson解析Json数据。SBJson文件来自GitHub,点击下载。将Classes 文件复制到工程中,任意添加一个Json数据即可。代码如下所示:


SBJson是一个开源的json库,结构如下:

结构主要分为:主头文件SBJson.h,一个对象类别扩展NSObject+SBJson.h,一个json解析包Parser,一个json编写包Writer

任何使用SBJson库的地方都要导入SBJson.h头文件

#import "SBJson.h" 

1.JSONObjective-C方法如下:

null    -> NSNull

string  -> Nsstring

array   -> NSMutableArray

object  -> NSMutableDictionary

true    -> NSNumber's -numberWithBool:YES

false   -> NSNumber's -numberWithBool:NO

integer up to 19 digits -> NSNumber's -numberWithLongLong:

all other numbers       -> NSDecimalNumber

truefalse转为 [NSNumber numberWithBool:YES][NSNumber numberWithBool:NO]

integer整数长度19位,表现为LongLong类型,[NSNumber numberWithLongLong:]

json允许大的离谱的数字,为避免任何精度损失,将其他复杂数变成NSDecimalNumber实例

2.Objective-CJSON方法如下:

NSNull        -> null

Nsstring      -> string

NSArray       -> array

NSDictionary  -> object

NSNumber's -initWithBool:YES -> true

NSNumber's -initWithBool:NO  -> false

NSNumber      -> number


注意:JSON中对象的键key必须是字符串

NSDictionary中的键key,可能不是字符串,所以当拥有非字符串的键的NSDictionary转为json时会抛出异常

主要两个接口:

[NSObjectJSONRepresentation]

[NsstringJSONValue]

一.NSObject+SBJson.h

1.把objc对象编码成json字符串

通过类别,为NSObject添加方法[NSObjectJSONRepresentation]

@H_243_502@1 @interface NSObject (NSObject_SBJsonWriting)
@H_243_502@2 /**@H_243_502@ @H_243_502@3  虽然定义成NSObject的类别,但仅对NSArray和NSDictionary有效
@H_243_502@4  返回:已编码的json对象,或nil
@H_243_502@5  */
@H_243_502@6 - (Nsstring *)JSONRepresentation;
@H_243_502@7 @end

2.json对象解析为objc对象

通过类别,为Nsstring添加方法:[NsstringJSONValue]

@H_243_502@1 @interface Nsstring (Nsstring_SBJsonParsing)
@H_243_502@2 /**
@H_243_502@3  返回:NSDictionary或NSArray对象,或nil
@H_243_502@4  */
@H_243_502@5 - (id)JSONValue;
@H_243_502@6 @end

二.NSObject+SBJson.m

导入头文件

@H_243_502@1 #import "NSObject+SBJson.h"
@H_243_502@2 #import "SBJsonWriter.h"
@H_243_502@3 #import "SBJsonParser.h"

1.通过json编写器SBJsonWriter,的stringWithObject: 方法,实现[NSObjectJSONRepresentation]编码逻辑

@H_243_502@ 1 @implementation NSObject (NSObject_SBJsonWriting)
@H_243_502@ 2 
@H_243_502@ 3 //objc2json
@H_243_502@ 4 - (Nsstring *)JSONRepresentation {
@H_243_502@ 5     SBJsonWriter *writer = [[SBJsonWriter alloc] init];    
@H_243_502@ 6     Nsstring *json = [writer stringWithObject:self];
@H_243_502@ 7     if (!json)
@H_243_502@ 8         NSLog(@"-JSONRepresentation Failed. Error is: %@",writer.error);
@H_243_502@ 9     return json;
@H_243_502@10 }
@H_243_502@11 
@H_243_502@12 @end

2.通过json解析器SBJsonParser,的objectWithString: 方法,实现[NsstringJSONValue]解析逻辑

@H_243_502@ 1 @implementation Nsstring (Nsstring_SBJsonParsing)
@H_243_502@ 2 
@H_243_502@ 3 //json2objc
@H_243_502@ 4 - (id)JSONValue {
@H_243_502@ 5     SBJsonParser *parser = [[SBJsonParser alloc] init];
@H_243_502@ 6     id repr = [parser objectWithString:self];
@H_243_502@ 7     if (!repr)
@H_243_502@ 8         NSLog(@"-JSONValue Failed. Error is: %@",parser.error);
@H_243_502@ 9     return repr;
@H_243_502@10 }
@H_243_502@11 
@H_243_502@12 @end

SBJsonWriter:json编写器类

内部使用了json流编写器:SBJsonStreamWriter类,和json流编写累加器:SBJsonStreamWriteraccumulator类

主要有4个属性

@H_243_502@ 1 /**
@H_243_502@ 2  @最大递归深度,认为32
@H_243_502@ 3  如果嵌套的太深,大于32被视为恶意解析,返回nil,并发送一个错误信号
@H_243_502@ 4  可以通过设置maxDepth为0,来取消此安全功能
@H_243_502@ 5  */
@H_243_502@ 6 @property NSUInteger maxDepth;
@H_243_502@ 7 
@H_243_502@ 8 /**
@H_243_502@ 9  @返回一个出错信息,如果没错误,返回为nil
@H_243_502@10  */
@H_243_502@11 @property (readonly,copy) Nsstring *error;
@H_243_502@12 
@H_243_502@13 /**
@H_243_502@14  @是否为人类可读的json
@H_243_502@15  认为NO,产生的json没有任何空白
@H_243_502@16  如果设为YES,换行后,每个数组值和字典键/值对缩进两个空格
@H_243_502@17  */
@H_243_502@18 @property BOOL humanReadable;
@H_243_502@19 
@H_243_502@20 /**
@H_243_502@21  @输出时字典键是否排序
@H_243_502@22  认为NO,如果设为YES,排序json输出的字典键
@H_243_502@23  如果你需要比较两个结构时候很有用
@H_243_502@24  */
@H_243_502@25 @property BOOL sortKeys;

注意:上面的error属性为只读的(readonly)

属性实现在SBJsonWriter.m文件中:

@H_243_502@1 @synthesize sortKeys;
@H_243_502@2 @synthesize humanReadable;
@H_243_502@3 @synthesize error;
@H_243_502@4 @synthesize maxDepth;

其中error通过类别声明为私有可写,如下:

@H_243_502@1 @interface SBJsonWriter ()
@H_243_502@2 @property (copy) Nsstring *error;
@H_243_502@3 @end

此类有3个转json表述的方法

@H_243_502@ 1 /**
@H_243_502@ 2  @objc转成Nsstring
@H_243_502@ 3  返回给定objc对象的json表示
@H_243_502@ 4  返回一个字符串,或nil
@H_243_502@ 5  如果返回nil,则SBJsonWriter的error属性不为空,可以通过error的信息知道出错原因
@H_243_502@ 6  其中的参数value,是任何可以用json表述的对象
@H_243_502@ 7  */
@H_243_502@ 8 - (Nsstring*)stringWithObject:(id)value;
@H_243_502@ 9 
@H_243_502@10 /**
@H_243_502@11  @objc转成NSData
@H_243_502@12  返回给定objc对象的json表示,用UTF8编码
@H_243_502@13  返回一个NSData对象,或nil
@H_243_502@14  */
@H_243_502@15 - (NSData*)dataWithObject:(id)value;
@H_243_502@16 
@H_243_502@17 /**
@H_243_502@18  @返回给定objc对象的json表示(或片段)
@H_243_502@19  返回字符串,或nil
@H_243_502@20  */
@H_243_502@21 - (Nsstring*)stringWithObject:(id)value
@H_243_502@22                            error:(NSError**)error;


三个方法的具体实现在SBJsonWriter.m文件

@H_243_502@ 1 //把objc转成NSData,再通过UTF8编码把NSData转成字符串
@H_243_502@ 2 - (Nsstring*)stringWithObject:(id)value {
@H_243_502@ 3     NSData *data = [self dataWithObject:value];
@H_243_502@ 4     if (data)
@H_243_502@ 5         return [[Nsstring alloc] initWithData:data encoding:NSUTF8StringEncoding];
@H_243_502@ 6     return nil;
@H_243_502@ 7 }    
@H_243_502@ 8 
@H_243_502@ 9 - (Nsstring*)stringWithObject:(id)value error:(NSError**)error_ {
@H_243_502@10     Nsstring *tmp = [self stringWithObject:value];
@H_243_502@11     if (tmp)
@H_243_502@12         return tmp;
@H_243_502@13     
@H_243_502@14     if (error_) {
@H_243_502@15         NSDictionary *ui = [NSDictionary dictionaryWithObjectsAndKeys:error,NSLocalizedDescriptionKey,nil];
@H_243_502@16         *error_ = [NSError errorWithDomain:@"org.brautaset.SBJsonWriter.ErrorDomain" code:0 userInfo:ui];
@H_243_502@17     }
@H_243_502@18     
@H_243_502@19     return nil;
@H_243_502@20 }
@H_243_502@21 
@H_243_502@22 /**
@H_243_502@23  初始化一个json流编写器,设置参数
@H_243_502@24  初始化一个json流编写叠加器,把它设为SBJsonStreamWriter的代理(delegate)
@H_243_502@25  把ojbc对象转变为NSData,通过调用SBJsonStreamWriter的writeObject:方法,或writeArray:方法@H_243_502@26  或递归调用dataWithObject:方法,参数为[object proxyForjson]返回的代理对象
@H_243_502@27  其中SBJsonStreamWriter的各种write方法,是把基本数据写成二进制bytes
@H_243_502@28  然后通过叠加器SBJsonStreamWriteraccumulator,把二进制bytes拼装成NSData对象
@H_243_502@29  返回叠加器的data属性变量
@H_243_502@30  */
@H_243_502@31 - (NSData*)dataWithObject:(id)object {    
@H_243_502@32     self.error = nil;
@H_243_502@33 
@H_243_502@34     SBJsonStreamWriteraccumulator *accumulator = [[SBJsonStreamWriteraccumulator alloc] init];
@H_243_502@35     
@H_243_502@36     SBJsonStreamWriter *streamWriter = [[SBJsonStreamWriter alloc] init];
@H_243_502@37     streamWriter.sortKeys = self.sortKeys;
@H_243_502@38     streamWriter.maxDepth = self.maxDepth;
@H_243_502@39     streamWriter.humanReadable = self.humanReadable;
@H_243_502@40     streamWriter.delegate = accumulator;
@H_243_502@41     
@H_243_502@42     BOOL ok = NO;
@H_243_502@43     if ([object isKindOfClass:[NSDictionary class]])
@H_243_502@44         ok = [streamWriter writeObject:object];
@H_243_502@45     
@H_243_502@46     else if ([object isKindOfClass:[NSArray class]])
@H_243_502@47         ok = [streamWriter writeArray:object];
@H_243_502@48         
@H_243_502@49     else if ([object respondsToSelector:@selector(proxyForjson)])
@H_243_502@50         return [self dataWithObject:[object proxyForjson]];
@H_243_502@51     else {
@H_243_502@52         self.error = @"Not valid type for JSON";
@H_243_502@53         return nil;
@H_243_502@54     }
@H_243_502@55     
@H_243_502@56     if (ok)
@H_243_502@57         return accumulator.data;
@H_243_502@58     
@H_243_502@59     self.error = streamWriter.error;
@H_243_502@60     return nil;    
@H_243_502@61 }


json流编写器

允许传入一个消息流对象,把它写入到SBJsonStreamWriteraccumulatordata.

1.里面含有个新的NSObject类别,把objc对象转成json允许的对象类型

@H_243_502@ 1 @interface NSObject (SBProxyForjson)
@H_243_502@ 2 
@H_243_502@ 3 /**
@H_243_502@ 4  json只支持NSArray和NSDictionary等类型
@H_243_502@ 5  所以转换之前先把特定objc对象转成这两种类型的形式
@H_243_502@ 6  如果你有一个自定义类,要把它转成json,需要实现该方法
@H_243_502@ 7  例子如下:
@H_243_502@ 8  @code
@H_243_502@ 9  - (id)proxyForjson {
@H_243_502@10  return [NSDictionary dictionaryWithObjectsAndKeys:
@H_243_502@11  name,@"name",@H_243_502@12  phone,@"phone",@H_243_502@13  email,@"email",@H_243_502@14  nil];
@H_243_502@15  }
@H_243_502@16  @endcode
@H_243_502@17  */
@H_243_502@18 
@H_243_502@19 - (id)proxyForjson;
@H_243_502@20 
@H_243_502@21 @end

2.里面定义了个json流编写器代理协议:

@H_243_502@1 //在json流编写叠加器SBJsonStreamWriteraccumulator里实现
@H_243_502@2 @protocol SBJsonStreamWriterDelegate
@H_243_502@3 
@H_243_502@4 - (void)writer:(SBJsonStreamWriter*)writer appendBytes:(const void *)bytes length:(NSUInteger)length;
@H_243_502@5 
@H_243_502@6 @end

3.定义了一个私有属性

NSMutableDictionary *cache;

4.定义了7个公有属性

@H_243_502@ 1 @property (nonatomic,unsafe_unretained) SBJsonStreamWriterState *state; // Internal
@H_243_502@ 2 @property (nonatomic,readonly,strong) NSMutableArray *stateStack; // Internal 
@H_243_502@ 3 
@H_243_502@ 4 //json输出流的代理
@H_243_502@ 5 @property (unsafe_unretained) id<SBJsonStreamWriterDelegate> delegate;
@H_243_502@ 6 
@H_243_502@ 7 /**
@H_243_502@ 8  @最大递归深度,认为512.
@H_243_502@ 9  如果嵌套的太深,大于32被视为恶意解析,返回nil,并发送一个错误信号
@H_243_502@10  可以通过设置maxDepth为0,来取消此安全功能
@H_243_502@11  */
@H_243_502@12 @property NSUInteger maxDepth;
@H_243_502@13 
@H_243_502@14 /**
@H_243_502@15  @是否为人类可读的json
@H_243_502@16  认为NO,产生的json没有任何空白
@H_243_502@17  如果设为YES,换行后,每个数组值和字典键/值对缩进两个空格
@H_243_502@18  */
@H_243_502@19 @property BOOL humanReadable;
@H_243_502@20 
@H_243_502@21 /**
@H_243_502@22  @输出时字典键是否排序
@H_243_502@23  认为NO,如果设为YES,排序json输出的字典键
@H_243_502@24  如果你需要比较两个结构时候很有用
@H_243_502@25  */
@H_243_502@26 @property BOOL sortKeys;
@H_243_502@27 
@H_243_502@28 /**
@H_243_502@29  @返回一个出错信息,如果没错误,返回为nil
@H_243_502@30  */
@H_243_502@31 @property (copy) Nsstring *error;

5.定义了10个公有方法

@H_243_502@ 1 /**
@H_243_502@ 2  把NSDictionary对象写到JSON输出@H_243_502@ 3  返回YES,表示成功
@H_243_502@ 4  */
@H_243_502@ 5 - (BOOL)writeObject:(NSDictionary*)dict;
@H_243_502@ 6 
@H_243_502@ 7 /**
@H_243_502@ 8  把NSArray对象写入JSON输出@H_243_502@ 9  返回YES,表示成功
@H_243_502@10  */
@H_243_502@11 - (BOOL)writeArray:(NSArray *)array;
@H_243_502@12 
@H_243_502@13 /**
@H_243_502@14  开始写一个obj对象到JSON输出@H_243_502@15  返回YES,表示成功
@H_243_502@16  */
@H_243_502@17 - (BOOL)writeObjectOpen;
@H_243_502@18 
@H_243_502@19 /**
@H_243_502@20  结束写obj对象到JSON输出@H_243_502@21  返回YES,表示成功
@H_243_502@22 */
@H_243_502@23 - (BOOL)writeObjectClose;
@H_243_502@24 
@H_243_502@25 /**
@H_243_502@26  开始写一个Array对象到JSON输出@H_243_502@27  返回YES,表示成功
@H_243_502@28  */
@H_243_502@29 - (BOOL)writeArrayOpen;
@H_243_502@30 
@H_243_502@31 /**
@H_243_502@32  结束写Array对象到JSON输出@H_243_502@33  返回YES,表示成功
@H_243_502@34  */
@H_243_502@35 - (BOOL)writeArrayClose;
@H_243_502@36 
@H_243_502@37 /**
@H_243_502@38  把null对象写入JSON输出@H_243_502@39  返回YES,表示成功
@H_243_502@40  */
@H_243_502@41 - (BOOL)writeNull;
@H_243_502@42 
@H_243_502@43 /**
@H_243_502@44  把boolean对象写入JSON输出@H_243_502@45  返回YES,表示成功
@H_243_502@46  */
@H_243_502@47 - (BOOL)writeBool:(BOOL)x;
@H_243_502@48 
@H_243_502@49 /**
@H_243_502@50  把Number对象写入JSON输出@H_243_502@51  返回YES,表示成功
@H_243_502@52  */
@H_243_502@53 - (BOOL)writeNumber:(NSNumber*)n;
@H_243_502@54 
@H_243_502@55 /**
@H_243_502@56  把String对象写入JSON输出@H_243_502@57  返回YES,表示成功
@H_243_502@58  */
@H_243_502@59 - (BOOL)writeString:(Nsstring*)s;

6.有个类别,定义了两个私有方法

@H_243_502@1 @interface SBJsonStreamWriter (Private)
@H_243_502@2 - (BOOL)writeValue:(id)v;
@H_243_502@3 - (void)appendBytes:(const void *)bytes length:(NSUInteger)length;
@H_243_502@4 @end


json流编写叠加器,拥有个可变data对象

@H_243_502@1 @interface SBJsonStreamWriteraccumulator : NSObject <SBJsonStreamWriterDelegate>
@H_243_502@2 
@H_243_502@3 @property (readonly,copy) NSMutableData* data;
@H_243_502@4 
@H_243_502@5 @end

具体实现:

@H_243_502@ 1 @implementation SBJsonStreamWriteraccumulator
@H_243_502@ 2 
@H_243_502@ 3 @synthesize data;
@H_243_502@ 4 
@H_243_502@ 5 - (id)init {
@H_243_502@ 6     self = [super init];
@H_243_502@ 7     if (self) {
@H_243_502@ 8         data = [[NSMutableData alloc] initWithCapacity:8096u];
@H_243_502@ 9     }
@H_243_502@10     return self;
@H_243_502@11 }
@H_243_502@12 
@H_243_502@13 
@H_243_502@14 #pragma mark SBJsonStreamWriterDelegate
@H_243_502@15 
@H_243_502@16 //实现SBJsonStreamWriterDelegate协议,把二进制数据添加到data
@H_243_502@17 
@H_243_502@18 - (void)writer:(SBJsonStreamWriter *)writer appendBytes:(const void *)bytes length:(NSUInteger)length {
@H_243_502@19     [data appendBytes:bytes length:length];
@H_243_502@20 }
@H_243_502@21 
@H_243_502@22 @end

json解析器

@H_243_502@ 1 /**
@H_243_502@ 2  json转objc
@H_243_502@ 3  解析json字符串和NSData对象
@H_243_502@ 4  内部使用了SBJsonStreamParser类
@H_243_502@ 5  */
@H_243_502@ 6 
@H_243_502@ 7 @interface SBJsonParser : NSObject
@H_243_502@ 8 
@H_243_502@ 9 /**
@H_243_502@10  @最大递归深度,认为32
@H_243_502@11  如果嵌套的太深,大于32被视为恶意解析,返回nil,并发送一个错误信号
@H_243_502@12  可以通过设置maxDepth为0,来取消此安全功能
@H_243_502@13  */
@H_243_502@14 @property NSUInteger maxDepth;
@H_243_502@15 
@H_243_502@16 /**
@H_243_502@17  @返回一个出错信息,如果没错误,返回为nil
@H_243_502@18  */
@H_243_502@19 @property(copy) Nsstring *error;
@H_243_502@20 
@H_243_502@21 /**
@H_243_502@22  json转objc
@H_243_502@23  @返回给定的NSData所代表的对象
@H_243_502@24  参数data必须为UTF8编码
@H_243_502@25  返回NSArray或NSDictionary对象,如果返回nil,表示出现错误
@H_243_502@26  */
@H_243_502@27 - (id)objectWithData:(NSData*)data;
@H_243_502@28 
@H_243_502@29 /**
@H_243_502@30  json转objc
@H_243_502@31  @返回给定字符串所代表的对象
@H_243_502@32 方法内部实现是:把参数用UTF8编码成NSData,然后调用objectWithData:方法,转成NSArray或NSDictionary,或nil
@H_243_502@33  */
@H_243_502@34 - (id)objectWithString:(Nsstring *)repr;
@H_243_502@35 
@H_243_502@36 /**
@H_243_502@37  json转objc
@H_243_502@38  @返回给定字符串所代表的对象
@H_243_502@39  */
@H_243_502@40 
@H_243_502@41 - (id)objectWithString:(Nsstring*)jsonText
@H_243_502@42                  error:(NSError**)error;
@H_243_502@43 
@H_243_502@44 @end

实现在SBJsonParser.m文件中:

@H_243_502@ 1 #import "SBJsonParser.h"
@H_243_502@ 2 #import "SBJsonStreamParser.h"
@H_243_502@ 3 #import "SBJsonStreamParserAdapter.h"
@H_243_502@ 4 #import "SBJsonStreamParserAccumulator.h"
@H_243_502@ 5 
@H_243_502@ 6 @implementation SBJsonParser
@H_243_502@ 7 
@H_243_502@ 8 @synthesize maxDepth;
@H_243_502@ 9 @synthesize error;
@H_243_502@10 
@H_243_502@11 - (id)init {
@H_243_502@12     self = [super init];
@H_243_502@13     if (self)
@H_243_502@14         self.maxDepth = 32u;
@H_243_502@15     return self;
@H_243_502@16 }
@H_243_502@17 
@H_243_502@18 #pragma mark Methods
@H_243_502@19 
@H_243_502@20 /**
@H_243_502@21  调用流解析器SBJsonStreamParser的parse:方法,把NSData转成NSArray或NSDictionary对象
@H_243_502@22  */
@H_243_502@23 - (id)objectWithData:(NSData *)data {
@H_243_502@24 
@H_243_502@25     if (!data) {
@H_243_502@26         self.error = @"Input was 'nil'";
@H_243_502@27         return nil;
@H_243_502@28     }
@H_243_502@29 
@H_243_502@30     //初始化一个json流解析叠加器
@H_243_502@31     SBJsonStreamParserAccumulator *accumulator = [[SBJsonStreamParserAccumulator alloc] init];
@H_243_502@32     
@H_243_502@33     //初始化一个json流解析配置器
@H_243_502@34     SBJsonStreamParserAdapter *adapter = [[SBJsonStreamParserAdapter alloc] init];
@H_243_502@35     //把叠加器设为配置器的代理(delegate)
@H_243_502@36     adapter.delegate = accumulator;
@H_243_502@37     
@H_243_502@38     //初始化一个json流解析器,设置参数
@H_243_502@39     SBJsonStreamParser *parser = [[SBJsonStreamParser alloc] init];
@H_243_502@40     parser.maxDepth = self.maxDepth;
@H_243_502@41     //配置器设为解析器的代理(delegate)
@H_243_502@42     parser.delegate = adapter;
@H_243_502@43     
@H_243_502@44     switch ([parser parse:data]) {
@H_243_502@45         case SBJsonStreamParserComplete:
@H_243_502@46             return accumulator.value;
@H_243_502@47             break;
@H_243_502@48             
@H_243_502@49         case SBJsonStreamParserWaitingForData:
@H_243_502@50             self.error = @"Unexpected end of input";
@H_243_502@51             break;
@H_243_502@52 
@H_243_502@53         case SBJsonStreamParserError:
@H_243_502@54             self.error = parser.error;
@H_243_502@55             break;
@H_243_502@56     }
@H_243_502@57     
@H_243_502@58     return nil;
@H_243_502@59 }
@H_243_502@60 
@H_243_502@61 //Nsstring用UTF8编码成NSData,再把NSData转成NSArray或NSDictionary对象
@H_243_502@62 - (id)objectWithString:(Nsstring *)repr {
@H_243_502@63     return [self objectWithData:[repr dataUsingEncoding:NSUTF8StringEncoding]];
@H_243_502@64 }
@H_243_502@65 
@H_243_502@66 - (id)objectWithString:(Nsstring*)repr error:(NSError**)error_ {
@H_243_502@67     id tmp = [self objectWithString:repr];
@H_243_502@68     if (tmp)
@H_243_502@69         return tmp;
@H_243_502@70     
@H_243_502@71     if (error_) {
@H_243_502@72         NSDictionary *ui = [NSDictionary dictionaryWithObjectsAndKeys:error,nil];
@H_243_502@73         *error_ = [NSError errorWithDomain:@"org.brautaset.SBJsonParser.ErrorDomain" code:0 userInfo:ui];
@H_243_502@74     }
@H_243_502@75     
@H_243_502@76     return nil;
@H_243_502@77 }
@H_243_502@78 
@H_243_502@79 @end


json数据流解析器

1.定义了一个枚举值表示解析状态:

@H_243_502@1 typedef enum {
@H_243_502@2     SBJsonStreamParserComplete,@H_243_502@3     SBJsonStreamParserWaitingForData,@H_243_502@4     SBJsonStreamParserError,@H_243_502@5 } SBJsonStreamParserStatus;

2.定义了一个json流解析代理协议:

@H_243_502@ 1 /**
@H_243_502@ 2  由SBJsonStreamParserAdapter类实现
@H_243_502@ 3  */
@H_243_502@ 4 @protocol SBJsonStreamParserDelegate
@H_243_502@ 5 
@H_243_502@ 6 //当找到obj时调用
@H_243_502@ 7 - (void)parserFoundobjectStart:(SBJsonStreamParser*)parser;
@H_243_502@ 8 
@H_243_502@ 9 //当找到obj对象key时调用
@H_243_502@10 - (void)parser:(SBJsonStreamParser*)parser foundobjectKey:(Nsstring*)key;
@H_243_502@11 
@H_243_502@12 //当obj结束时调用
@H_243_502@13 - (void)parserFoundobjectEnd:(SBJsonStreamParser*)parser;
@H_243_502@14 
@H_243_502@15 //当找到array对象时调用
@H_243_502@16 - (void)parserFoundarrayStart:(SBJsonStreamParser*)parser;
@H_243_502@17 
@H_243_502@18 //当array对象结束时调用
@H_243_502@19 - (void)parserFoundarrayEnd:(SBJsonStreamParser*)parser;
@H_243_502@20 
@H_243_502@21 //当找到boolean值时调用
@H_243_502@22 - (void)parser:(SBJsonStreamParser*)parser foundBoolean:(BOOL)x;
@H_243_502@23 
@H_243_502@24 //当找到null时调用
@H_243_502@25 - (void)parserFoundNull:(SBJsonStreamParser*)parser;
@H_243_502@26 
@H_243_502@27 //当找到number时调用
@H_243_502@28 - (void)parser:(SBJsonStreamParser*)parser foundNumber:(NSNumber*)num;
@H_243_502@29 
@H_243_502@30 //当找到字符串对象时调用
@H_243_502@31 - (void)parser:(SBJsonStreamParser*)parser foundString:(Nsstring*)string;
@H_243_502@32 
@H_243_502@33 @end

3.属性和声明的方法

@H_243_502@ 1 /**
@H_243_502@ 2  @json数据流解析器
@H_243_502@ 3  把json数据流解析成NSArray或NSDictionary对象
@H_243_502@ 4  使用这个类,可以边下载边解析(在整个文件被全部下载之前进行解析)
@H_243_502@ 5  用这个类对磁盘上的大文件解析也有好处,不用全部加载到内存
@H_243_502@ 6  具体实现可查看SBJsonStreamParserAdapter类
@H_243_502@ 7  */
@H_243_502@ 8 @interface SBJsonStreamParser : NSObject {
@H_243_502@ 9 @private
@H_243_502@10     SBJsonTokeniser *tokeniser;
@H_243_502@11 }
@H_243_502@12 
@H_243_502@13 @property (nonatomic,unsafe_unretained) SBJsonStreamParserState *state; // Private
@H_243_502@14 @property (nonatomic,strong) NSMutableArray *stateStack; // Private
@H_243_502@15 
@H_243_502@16 /**
@H_243_502@17  是否用空格隔开多个文件
@H_243_502@18  当设置为YES,解析器就不会返回SBJsonStreamParserComplete
@H_243_502@19  认为NO,一但返回SBJsonStreamParserComplete,解析器不会解析更多数据
@H_243_502@20  */
@H_243_502@21 @property BOOL supportMultipleDocuments;
@H_243_502@22 
@H_243_502@23 /**
@H_243_502@24  @流解析代理对象
@H_243_502@25  通常是指SBJsonStreamParserAdapter
@H_243_502@26  也可以是实现了SBJsonStreamParserDelegate解析代理协议的任何对象
@H_243_502@27  */
@H_243_502@28 @property (unsafe_unretained) id<SBJsonStreamParserDelegate> delegate;
@H_243_502@29 
@H_243_502@30 /**
@H_243_502@31  @最大递归深度,认为32
@H_243_502@32  如果嵌套的太深,大于32被视为恶意解析,返回nil,并发送一个错误信号
@H_243_502@33  */
@H_243_502@34 @property NSUInteger maxDepth;
@H_243_502@35 
@H_243_502@36 //保存BJsonStreamParserError后返回的错误信息
@H_243_502@37 @property (copy) Nsstring *error;
@H_243_502@38 
@H_243_502@39 /**
@H_243_502@40  解析json数据
@H_243_502@41  参数是UTF8编码的json数据(NSData)
@H_243_502@42  返回一个枚举值,流解析状态:
@H_243_502@43  SBJsonStreamParserComplete表示:解析了全部数据
@H_243_502@44  SBJsonStreamParserWaitingForData表示:等待获得更多数据
@H_243_502@45  SBJsonStreamParserError表示:解析出错
@H_243_502@46  */
@H_243_502@47 - (SBJsonStreamParserStatus)parse:(NSData*)data;
@H_243_502@48 
@H_243_502@49 @end

json流解析配置器

1.定义了一个枚举配置器类型:

@H_243_502@1 typedef enum {
@H_243_502@2     SBJsonStreamParserAdapterNone,@H_243_502@3     SBJsonStreamParserAdapterarray,@H_243_502@4     SBJsonStreamParserAdapterObject,@H_243_502@5 } SBJsonStreamParserAdapterType;

2.定义了一个json流解析配置器代理协议:

@H_243_502@ 1 /**
@H_243_502@ 2  @json流解析配置器代理协议
@H_243_502@ 3  从流解析配置器获得obj或array对象的代理
@H_243_502@ 4  由流解析叠加器SBJsonStreamParserAccumulator实现
@H_243_502@ 5  */
@H_243_502@ 6 @protocol SBJsonStreamParserAdapterDelegate
@H_243_502@ 7 
@H_243_502@ 8 /**
@H_243_502@ 9  如果发现一个json数组,则调用方法
@H_243_502@10  */
@H_243_502@11 - (void)parser:(SBJsonStreamParser*)parser foundarray:(NSArray*)array;
@H_243_502@12 
@H_243_502@13 /**
@H_243_502@14  如果发现一个json对象,则调用方法
@H_243_502@15  */
@H_243_502@16 - (void)parser:(SBJsonStreamParser*)parser foundobject:(NSDictionary*)dict;
@H_243_502@17 
@H_243_502@18 @end

3.类定义属性

@H_243_502@ 1 @interface SBJsonStreamParserAdapter : NSObject <SBJsonStreamParserDelegate> {
@H_243_502@ 2 @private
@H_243_502@ 3     NSUInteger depth;
@H_243_502@ 4     NSMutableArray *array;
@H_243_502@ 5     NSMutableDictionary *dict;
@H_243_502@ 6     NSMutableArray *keyStack;
@H_243_502@ 7     NSMutableArray *stack;
@H_243_502@ 8     
@H_243_502@ 9     SBJsonStreamParserAdapterType currentType;
@H_243_502@10 }
@H_243_502@11 
@H_243_502@12 /**
@H_243_502@13  如何跳过多个层级
@H_243_502@14 文件太大了或链接缓慢,此方法相当有用
@H_243_502@15  如果设置此为N,它会跳过外面的N层,为每个内层对象,直接调用-parser:foundarray:或-parser:foundobject:方法
@H_243_502@16  */
@H_243_502@17 @property NSUInteger levelsToSkip;
@H_243_502@18 
@H_243_502@19 /**
@H_243_502@20  实现SBJsonStreamParserAdapterDelegate代理协议的对象
@H_243_502@21  */
@H_243_502@22 @property (unsafe_unretained) id<SBJsonStreamParserAdapterDelegate> delegate;
@H_243_502@23 
@H_243_502@24 @end

/**

认的委托,当一个文件完全解析,只会调用一个-parser:foundarray:方法-parser:foundobject:方法

如果设置SBJsonStreamParsersupportMultipleDocuments属性YES,

就可以支持多个json顶级对象的解析

例子如下:

@code

SBJsonStreamParserAdapter *adapter = [[[SBJsonStreamParserAdapter alloc] init] autorelease];

adapter.delegate = self;

SBJsonStreamParser *parser = [[[SBJsonStreamParser alloc] init] autorelease];

parser.delegate = adapter;

parser.supportMultipleDocuments = YES;

// 注意:此输入包含多个顶级json对象

NSData *json = [@"[]{}[]{}" dataWithEncoding:NSUTF8StringEncoding];

[parser parse:data];

@endcode

self调用它的顺序如下:

@li -parser:foundarray:

@li -parser:foundobject:

@li -parser:foundarray:

@li -parser:foundobject:

下面是跳过第一个或多个封装对象:

@code

SBJsonStreamParserAdapter *adapter = [[[SBJsonStreamParserAdapter alloc] init] autorelease];

adapter.delegate = self;

adapter.levelsToSkip = 1;

SBJsonStreamParser *parser = [[[SBJsonStreamParser alloc] init] autorelease];

parser.delegate = adapter;

// 注意:此输入包含一个单一的顶级json对象

NSData *json = [@"[[],{},[],{}]" dataWithEncoding:NSUTF8StringEncoding];

[parser parse:data];

@endcode

*/


json流解析叠加器

@H_243_502@1 //实现了流解析配置代理协议
@H_243_502@2 @interface SBJsonStreamParserAccumulator : NSObject <SBJsonStreamParserAdapterDelegate>
@H_243_502@3 
@H_243_502@4 //声明的value对象,表示解析完成后的objc对象
@H_243_502@5 @property (copy) id value;
@H_243_502@6 
@H_243_502@7 @end

json流解析叠加器

@H_243_502@1 //实现了流解析配置代理协议
@H_243_502@2 @interface SBJsonStreamParserAccumulator : NSObject <SBJsonStreamParserAdapterDelegate>
@H_243_502@3 
@H_243_502@4 //声明的value对象,表示解析完成后的objc对象
@H_243_502@5 @property (copy) id value;
@H_243_502@6 
@H_243_502@7 @end

实现了配置代理协议SBJsonStreamParserAdapterDelegate的两个方法

@H_243_502@ 1 /**
@H_243_502@ 2  返回NSArray或NSDictionary对象
@H_243_502@ 3  */
@H_243_502@ 4 - (void)parser:(SBJsonStreamParser*)parser foundarray:(NSArray *)array {
@H_243_502@ 5     value = array;
@H_243_502@ 6 }
@H_243_502@ 7 
@H_243_502@ 8 - (void)parser:(SBJsonStreamParser*)parser foundobject:(NSDictionary *)dict {
@H_243_502@ 9     value = dict;
@H_243_502@10 }
来自:http://www.cnblogs.com/xiaodao/archive/2012/02/17/2355893.html

相关文章

AJAX是一种基于JavaScript和XML的技术,能够使网页实现异步交...
在网页开发中,我们常常需要通过Ajax从后端获取数据并在页面...
在前端开发中,经常需要循环JSON对象数组进行数据操作。使用...
AJAX(Asynchronous JavaScript and XML)是一种用于创建 We...
AJAX技术被广泛应用于现代Web开发,它可以在无需重新加载页面...
Ajax是一种通过JavaScript和HTTP请求交互的技术,可以实现无...