0

NSCoderクラスに必要なようですが、これとそれに対応するメソッドの実際の例を見ることができれば便利です。

私がそれを必要と感じる理由は、私のメソッドがNSString *のencodeObjectを試みたときに、次のように文句を言うからです。

キャッチされなかった例外'NSInvalidArgumentException'が原因でアプリを終了しています。理由:' * -encodeBytes:length:forKey:抽象クラスに対してのみ定義されています。定義-[JSONEncoderencodeBytes: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タイプでも機能し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なりますが、このように使用することを意図しているかどうかはわかりません。

于 2013-02-22T21:51:17.860 に答える