2013-02-22 78 views
0

我明显需要它用于我的NSCoder类,如果我能看到这个及其相应方法的实例,那将会非常有用。有没有人有使用encodeBytes的示例代码:length:forKey:?

的原因,我觉得我需要它是当我的方法试图encodeObject为一个NSString *,它抱怨说:

终止应用程序由于未捕获的异常“NSInvalidArgumentException”,原因是:“* -encodeBytes:长度:forKey:仅为抽象类定义。定义 - [JSONEncoder encodeBytes:length:forKey:]!'

谢谢。

JSONEncoder中的方法:(https://github.com/ontometrics/JSONCoding)我无法使静态库的工作,所以我试图直接与代码工作。

- (void)encodeObject:(id)object { 
    [self push:object]; 
    [object encodeWithCoder:self]; 

    finalJSONObject = [NSDictionary dictionaryWithObject:[self topObject] forKey:[[[object class] description] camelcaseString]]; 

    [self pop]; 
} 
+0

http://www.mikeash.com/pyblog/friday-qa-2010-08-12-implementing-nscoding.html – trojanfoe 2013-02-22 16:09:10

+0

博客提到该方法,但没有给出示例代码。 – 2013-02-22 16:37:09

+1

@AaronBratcher:或许你应该展示你的班级的定义以及你迄今为止的尝试。帮助解决具体问题更容易。 – 2013-02-22 18:04:24

回答

0

我认为JSONEncoder主要是指编码从自定义类对象(必须实现NSCoding协议)。例如,如果你定义一个类Person一个字符串属性:

@interface Person : NSObject <NSCoding> 
@property(strong, nonatomic) NSString *name; 
@end 

@implementation Person 
- (id)initWithCoder:(NSCoder *)coder { 
    if ((self = [super init])) { 
     self.name = [coder decodeObjectForKey:@"name"]; 
    } 
    return self; 
} 

- (void)encodeWithCoder:(NSCoder *)coder { 
    [coder encodeObject:self.name forKey:@"name"]; 
} 
@end 

那么你可以使用JSONEncoder编码没有问题这个类的一个对象:

JSONEncoder *encoder = [JSONEncoder encoder]; 
Person *obj = [[Person alloc] init]; 
obj.name = @"John"; 
[encoder encodeObject:obj]; 
NSString *json = [encoder json]; 
NSLog(@"%@", json); 
// Output: {"person":{"name":"John"}} 

它的工作原理也与一些“纯”基础类型,例如与NSNumber,但输出是不是很“漂亮”,我不知道,如果JSONEncoder意味着这样使用:

JSONEncoder *encoder = [JSONEncoder encoder]; 
NSNumber *obj = @1234; 
[encoder encodeObject:obj]; 
NSString *json = [encoder json]; 
NSLog(@"%@", json); 
// Output: {"__NSCFNumber":{"NS.intval":1234}} 

在这种情况下,JSONEncoderencodeInt64:forKey:方法在内部调用。

然而,当你注意到没有,它不与NSString工作:

JSONEncoder *encoder = [JSONEncoder encoder]; 
NSString *obj = @"Hello world"; 
[encoder encodeObject:obj]; 
// Exception: *** -encodeBytes:length:forKey: only defined for abstract class. Define -[JSONEncoder encodeBytes:length:forKey:]! 

的原因的例外是,NSStringNSCoding兼容,但它使用的编码器的-encodeBytes:length:forKey:,并JSONEncoder不实施此方法

实施该方法是不是太困难,这是一个快速和肮脏的尝试:

- (void)encodeBytes:(const uint8_t *)bytesp length:(NSUInteger)lenv forKey:(NSString *)key 
{ 
    NSString *s = [[NSString alloc] initWithBytes:bytesp length:lenv encoding:NSUTF8StringEncoding]; 
    [self setObject:s forKey:key]; 
} 

如果添加此代码为“JSONEncoder.m”,那么你就可以编码一个普通NSString没有得到一个例外,结果是这样的:

{"__NSCFConstantString":{"NS.bytes":"Hello world"}} 

但同样,我不知道如果JSONEncoder意味着这样使用。

+0

以及我愿意尝试它。我不认为你有相反的方式来取回字符串? – 2013-02-22 22:43:49

+0

@AaronBratcher:我再次想到了这件事。根据http://www.ietf.org/rfc/rfc4627.txt,*“JSON文本是一个序列化的对象或数组”,而一个对象是一个集合名称/值对。换句话说,顶层JSON对象总是一个字典或数组。因此,将单个字符串编码为JSON没有多大意义。我认为你应该把你的字符串包装到一个自定义类中并对其进行编码。 - 顺便说一句。为什么你需要JSONEncoder? NSDictionary和NSArray可以使用内置的NSJSONSerialization类进行编码。 – 2013-02-23 10:25:43

+0

字符串应该以这种方式编码为对象:variableName:value。很像使用JSONEncoder进行编码的其他类型。我想接收和发送JSON到我的服务器,并直接解析它进/出我的自定义类。 – 2013-02-23 13:22:14

相关问题