使用 yajl-objc 编码自定义类
总结。基于一些基准,我选择yajl-objc 用于我的 iPhone JSON 解析器。我正在使用任意自定义类(一个 NSNumber 和两个 NSString 属性)对其进行测试。如果我创建了一个具有与类属性匹配的键值对的 NSDictionary,我可以使用 [dictionary yajl_JSON]
对字典进行编码。当我尝试使用 [custom yajl_JSON]
直接对自定义类的实例进行编码时,出现以下编译器错误:
由于未捕获的异常“YAJLParsingUnsupportedException”而终止应用程序,原因:“对象类型 (自定义)必须实现 dataUsingEncoding: 才能解析'
。
即使我实现了 - (id)JSON
(如 yajl-objc 自述文件)。我知道问题出在我的代码上,而不是库上。我只是不明白我做错了什么。
详细信息。 我的 Custom.h:
#import
@interface Custom : NSObject {
NSString *name;
NSNumber *number;
NSString *text;
}
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSNumber *number;
@property (nonatomic, copy) NSString *text;
@end
在 Custom.m 中,我根据 yajl-obj 文档定义了一个 - (id)JSON
方法:
- (id)JSON
{
NSDictionary *jsonDictionary =
[[[NSMutableDictionary alloc] init] autorelease];
[jsonDictionary setValue:name forKey:@"name"];
[jsonDictionary setValue:number forKey:@"number"];
[jsonDictionary setValue:text forKey:@"text"];
return jsonDictionary;
}
创建键值匹配字典并编码它工作正常:
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setValue:self.custom.name forKey:@"name"];
[dict setValue:self.custom.number forKey:@"number"];
[dict setValue:self.custom.text forKey:@"text"];
NSString *JSONString = [dict yajl_JSON];
但是当我调用 NSString* JSONString = [custom yajl_JSON]
;这是我得到的编译器错误和堆栈跟踪:
*** Terminating app due to uncaught exception 'YAJLParsingUnsupportedException', reason: 'Object of type (Custom) must implement dataUsingEncoding: to be parsed'
*** Call stack at first throw:
(
0 CoreFoundation 0x0266bb99 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x027bb40e objc_exception_throw + 47
2 CoreFoundation 0x02624238 +[NSException raise:format:arguments:] + 136
3 CoreFoundation 0x026241aa +[NSException raise:format:] + 58
4 TestCustomFileFormat 0x00005151 -[NSObject(YAJL) yajl_JSONWithOptions:error:] + 206
5 TestCustomFileFormat 0x00005212 -[NSObject(YAJL) yajl_JSON:] + 49
6 TestCustomFileFormat 0x00005249 -[NSObject(YAJL) yajl_JSON] + 49
7 TestCustomFileFormat 0x00002eba -[TestViewController loadInstruction] + 758
8 TestCustomFileFormat 0x00002aa5 -[TestViewController viewDidLoad] + 77
9 UIKit 0x0037585a -[UIViewController view] + 179
10 TestCustomFileFormat 0x00002377 -[TestCustomFileFormatAppDelegate application:didFinishLaunchingWithOptions:] + 112
11 UIKit 0x002cc6a7 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1163
12 UIKit 0x002ceb30 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 346
13 UIKit 0x002d8b6c -[UIApplication handleEvent:withNewEvent:] + 1958
14 UIKit 0x002d12bc -[UIApplication sendEvent:] + 71
15 UIKit 0x002d613f _UIApplicationHandleEvent + 7672
16 GraphicsServices 0x02f4b81e PurpleEventCallback + 1578
17 CoreFoundation 0x0264cff4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
18 CoreFoundation 0x025ad807 __CFRunLoopDoSource1 + 215
19 CoreFoundation 0x025aaa93 __CFRunLoopRun + 979
20 CoreFoundation 0x025aa350 CFRunLoopRunSpecific + 208
21 CoreFoundation 0x025aa271 CFRunLoopRunInMode + 97
22 UIKit 0x002ce3ed -[UIApplication _run] + 625
23 UIKit 0x002da272 UIApplicationMain + 1160
24 TestCustomFileFormat 0x000022e4 main + 102
25 TestCustomFileFormat 0x00002275 start + 53
)
terminate called after throwing an instance of 'NSException'
作为响应,我尝试遵循 NSCoding,使用 NSKeyedArchiver 创建类实例的 NSMutableData 表示形式并调用 [data yajl_JSON]
,但这不起作用任何一个。
我知道我错过了一些简单的事情,但我太愚蠢了,无法弄清楚。
Summary. Based on some benchmarks, I chose yajl-objc for my iPhone JSON parser. I was testing it with an arbitrary custom class (one NSNumber and two NSString properties). If I created an NSDictionary with key-value pairs matching the class properties, I could encode the dictionary with [dictionary yajl_JSON]
. When I tried directly encoding an instance of the custom class with [custom yajl_JSON]
, I got this compiler error:
Terminating app due to uncaught exception 'YAJLParsingUnsupportedException', reason: 'Object of type (Custom) must implement dataUsingEncoding: to be parsed'
.
I got the error even when I implemented - (id)JSON
(as suggested in the yajl-objc readme). I know my code, not the library, is the problem. I just can't figure out what I'm doing wrong.
Details. My Custom.h:
#import
@interface Custom : NSObject {
NSString *name;
NSNumber *number;
NSString *text;
}
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSNumber *number;
@property (nonatomic, copy) NSString *text;
@end
In Custom.m, I defined an - (id)JSON
method per the yajl-obj documentation:
- (id)JSON
{
NSDictionary *jsonDictionary =
[[[NSMutableDictionary alloc] init] autorelease];
[jsonDictionary setValue:name forKey:@"name"];
[jsonDictionary setValue:number forKey:@"number"];
[jsonDictionary setValue:text forKey:@"text"];
return jsonDictionary;
}
Creating a key-value matched dictionary and encoding it works fine:
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setValue:self.custom.name forKey:@"name"];
[dict setValue:self.custom.number forKey:@"number"];
[dict setValue:self.custom.text forKey:@"text"];
NSString *JSONString = [dict yajl_JSON];
But when I call NSString* JSONString = [custom yajl_JSON]
; here's the compiler error and stack trace I get:
*** Terminating app due to uncaught exception 'YAJLParsingUnsupportedException', reason: 'Object of type (Custom) must implement dataUsingEncoding: to be parsed'
*** Call stack at first throw:
(
0 CoreFoundation 0x0266bb99 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x027bb40e objc_exception_throw + 47
2 CoreFoundation 0x02624238 +[NSException raise:format:arguments:] + 136
3 CoreFoundation 0x026241aa +[NSException raise:format:] + 58
4 TestCustomFileFormat 0x00005151 -[NSObject(YAJL) yajl_JSONWithOptions:error:] + 206
5 TestCustomFileFormat 0x00005212 -[NSObject(YAJL) yajl_JSON:] + 49
6 TestCustomFileFormat 0x00005249 -[NSObject(YAJL) yajl_JSON] + 49
7 TestCustomFileFormat 0x00002eba -[TestViewController loadInstruction] + 758
8 TestCustomFileFormat 0x00002aa5 -[TestViewController viewDidLoad] + 77
9 UIKit 0x0037585a -[UIViewController view] + 179
10 TestCustomFileFormat 0x00002377 -[TestCustomFileFormatAppDelegate application:didFinishLaunchingWithOptions:] + 112
11 UIKit 0x002cc6a7 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1163
12 UIKit 0x002ceb30 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 346
13 UIKit 0x002d8b6c -[UIApplication handleEvent:withNewEvent:] + 1958
14 UIKit 0x002d12bc -[UIApplication sendEvent:] + 71
15 UIKit 0x002d613f _UIApplicationHandleEvent + 7672
16 GraphicsServices 0x02f4b81e PurpleEventCallback + 1578
17 CoreFoundation 0x0264cff4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
18 CoreFoundation 0x025ad807 __CFRunLoopDoSource1 + 215
19 CoreFoundation 0x025aaa93 __CFRunLoopRun + 979
20 CoreFoundation 0x025aa350 CFRunLoopRunSpecific + 208
21 CoreFoundation 0x025aa271 CFRunLoopRunInMode + 97
22 UIKit 0x002ce3ed -[UIApplication _run] + 625
23 UIKit 0x002da272 UIApplicationMain + 1160
24 TestCustomFileFormat 0x000022e4 main + 102
25 TestCustomFileFormat 0x00002275 start + 53
)
terminate called after throwing an instance of 'NSException'
In response, I tried conforming to NSCoding, used NSKeyedArchiver to create an NSMutableData representation of the class instance and called [data yajl_JSON]
, but that didn't work either.
I know I'm missing something simple, but I'm too stupid to figure it out.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你这样做的方式是错误的。要从对象创建 JSON 字符串,请使用
yajl_JSONString
。 yail_JSON 用来获取字符串(或 NSData 对象或可以存档的对象)并将其解析为对象。You’re doing it the wrong way around. To create a JSON string from an object you use
yajl_JSONString
.yail_JSON
is there to take a string (or aNSData
object or something that can be archived) and parse that into objects.