2013-02-22 96 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

相關問題