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タイプでも機能し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:]!
例外の理由は、NSString
準拠NSCoding
している-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
なりますが、このように使用することを意図しているかどうかはわかりません。