0

我的 NSCoder 类显然需要它,如果我能看到一个真实的例子及其相应的方法,那将会很有用。

我觉得我需要它的原因是当我的方法尝试为 NSString* 编码对象时,它抱怨说:

由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“ * -encodeBytes:length: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];
}
4

1 回答 1

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"}}

它也适用于一些“普通”的 Foundation 类型,例如 with NSNumber,但输出不是很“好”,我不确定是否JSONEncoder打算这样使用:

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

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

但是,正如您所注意到的,它不适用于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要这样使用。

于 2013-02-22T21:51:17.860 回答