代码之家  ›  专栏  ›  技术社区  ›  Marci-man

实现NSCoding协议以将对象发送到基于Java的服务器

  •  0
  • Marci-man  · 技术社区  · 10 年前

    几天前我问过一个类似的问题。。。
    虽然我已经取得了一些进展,但我似乎仍然无法让它发挥作用。

    这是我到现在为止所做的:

    自定义可写对象:

    @interface customWriteableObj : NSObject <NSCoding>
    @property int integer;
    @property NSString * string;
    @property BOOL boo;
    @end
    

    自定义可写对象:

    #import "customWriteableObj.h"
    
    @implementation customWriteableObj
    -(id)init
    {
        _integer = 117;
        _string = @"aString";
        _boo = YES;
        return self;
    }
    -(id)initWithCoder:(NSCoder *)aDecoder
    {
        _integer = [aDecoder decodeIntForKey:@"integer"];
        _boo = [aDecoder decodeBoolForKey:@"boo"];
        _string = [aDecoder decodeObjectForKey:@"string"];
        return self;
    }
    
    -(void)encodeWithCoder:(NSCoder *)aCoder
    {
        [aCoder encodeObject:self.string forKey:@"string"];
        [aCoder encodeBool:self.boo forKey:@"boo"];
        [aCoder encodeInteger:self.integer forKey:@"integer"];
    }
    @end
    

    主要:

    customWriteableObj * x = [[customWriteableObj alloc]init];
        NSMutableData *dat = [[NSMutableData alloc] init];
        NSKeyedArchiver* arch1 = [[NSKeyedArchiver alloc]initForWritingWithMutableData:dat];
        arch1.outputFormat = NSPropertyListXMLFormat_v1_0;
        [arch1 encodeObject:x forKey:@"tester1"];
        [arch1 finishEncoding];
    
        [dat writeToFile:@"text.xml";
        customWriteableObj * y = [[customWriteableObj alloc]init];
        y = [NSKeyedUnarchiver unarchiveObjectWithFile:@"text.xml";
    

    XML输出:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>$archiver</key>
        <string>NSKeyedArchiver</string>
        <key>$objects</key>
        <array>
            <string>$null</string>
            <dict>
                <key>$class</key>
                <dict>
                    <key>CF$UID</key>
                    <integer>3</integer>
                </dict>
                <key>boo</key>
                <true/>
                <key>integer</key>
                <integer>117</integer>
                <key>string</key>
                <dict>
                    <key>CF$UID</key>
                    <integer>2</integer>
                </dict>
            </dict>
            <string>aString</string>
            <dict>
                <key>$classes</key>
                <array>
                    <string>customWriteableObj</string>
                    <string>NSObject</string>
                </array>
                <key>$classname</key>
                <string>customWriteableObj</string>
            </dict>
        </array>
        <key>$top</key>
        <dict>
            <key>tester1</key>
            <dict>
                <key>CF$UID</key>
                <integer>1</integer>
            </dict>
        </dict>
        <key>$version</key>
        <integer>100000</integer>
    </dict>
    </plist>
    

    这似乎不正确,因为我在这里看不到任何数据,而且,当我试图读回它时,我得到了一个零!
    我还需要将此对象持久化到基于java的服务器上的数据库中。。。

    2 回复  |  直到 10 年前
        1
  •  1
  •   Dima    10 年前

    乍一看,你好像错过了 super 调用init方法。这意味着您重写了这些初始化方法,而实际上从未初始化过对象。所以当你反序列化时,你会得到 nil 。这将修复它:

    -(id)init
    {
       if(self = [super init])
       {
            _integer = 117;
            _string = @"aString";
            _boo = YES;
       }
       return self;
    }
    
    -(id)initWithCoder:(NSCoder *)aDecoder
    {
        if(self = [self init])
        {
            _integer = [aDecoder decodeIntForKey:@"integer"];
            _boo = [aDecoder decodeBoolForKey:@"boo"];
            _string = [aDecoder decodeObjectForKey:@"string"];
        }
        return self;
    }
    

    EDIT with JSON序列化示例

    在自定义对象类上创建一个方法,将对象转换为可序列化字典。它可能看起来像:

    - (NSDictionary *) jsonDictionary
    {
        return @{@"integer": @(_integer), @"boo": @(_boo), @"string" : _string};
    }
    

    然后,只要您准备好将数组中的所有对象发送过来,就可以对它们进行迭代调用。这可能看起来像:

    // Assuming you have an NSArray called customObjects
    
    NSMutableArray *customObjectsJSON = [[NSMutableArray alloc] initWithCapacity:customObjects.count];
    for(customWriteableObj *object in customObjects)
    {
        [customObjectsJSON addObject:[object jsonDictionary]];
    }
    

    此时, customObjectsJSON 准备好设置为网络请求的参数。根据您使用的其他工具,您可能需要自己使用将其转换为JSON NSJSONSerialization

        2
  •  1
  •   Wain    10 年前

    看起来是正确的。在XML中,您可以看到 117 aString 价值观XML是一种自定义格式,因此您通常不应将其用于存储和重新加载以外的任何用途。

    当您尝试重新加载存档时,您的结果对象为空,因为您的重新加载方式与存档方式不同(在结构方面)。如果您使用 [arch1 encodeObject:x forKey:@"tester1"]; 那么您需要与 initForReadingWithData: decodeObjectForKey: .