【问题标题】:Converting a NSObject into NSData将 NSObject 转换为 NSData
【发布时间】:2009-11-02 07:50:18
【问题描述】:

我在将 NSObject 转换为 NSData 时遇到问题。我有一个继承 NSObject 的类。

当我尝试将该特定类的对象转换为 NSData 时,如下所示:

NSData *dataOnObject = [NSKeyedArchiver archivedDataWithRootObject:classObject];

但它给出了异常说明-[classObject encodeWithCoder:]:无法识别的选择器发送到实例..

我还将对象添加到新创建的数组中

NSMutableArray *wrapperedData = [NSMutableArray arrayWithObject: classObject];
NSData *dataOnObject = [NSKeyedArchiver archivedDataWithRootObject:value];

但是,它仍然发出异常。

所以我需要从对象classObject 中提取字节。

任何帮助将不胜感激...

等待您的回复...

【问题讨论】:

    标签: iphone


    【解决方案1】:

    您必须为自己的对象实现,例如:

    - (void)encodeWithCoder:(NSCoder *)aCoder
    {
        [aCoder encodeObject:self.name forKey:@"name"];
        [aCoder encodeInt:self.age forKey:@"age"];
        [aCoder encodeObject:self.email forKey:@"email"];
        [aCoder encodeObject:self.password forKey:@"password"];
    }
    BOOL success = [NSKeyedArchiver archiveRootObject:person toFile:archiveFilePath];
    

    和:

    - (id)initWithCoder:(NSCoder *)aDecoder
    {
        if (self = [super init]) {
            self.name = [aDecoder decodeObjectForKey:@"name"];
            self.age = [aDecoder decodeIntForKey:@"age"];
            self.email = [aDecoder decodeObjectForKey:@"email"];
            self.password = [aDecoder decodeObjectForKey:@"password"];
        }
        return self;
    }
    Person *unarchivePerson = [NSKeyedUnarchiver unarchiveObjectWithFile:archiveFilePath];
    

    【讨论】:

      【解决方案2】:

      您需要在您的自定义类上实现 encodeWithCoder:,使用传递给它的 NSCoder 序列化其所有属性。如果它的属性包含更多自定义类,它们也需要 encodeWithCoder: 实现。

      【讨论】:

        【解决方案3】:

        代替

        NSData *dataOnObject = [NSKeyedArchiver archivedDataWithRootObject:classObject];
        

        应该是

        NSData *dataOnObject = [[NSUserDefaults standardUserDefaults] objectForKey:@"someKey"];
        

        但这只是为了读取已经保存的数据。如果你想将一个对象保存为 NSData 那么你有这个:

        [[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:classObject] forKey:@"someKey"];
        

        但这还不是全部。您的 classObject 必须实现 NSCoding 协议并具有两个方法 encodeWithCoder: 和 initWithCoder: 因为它不是 NS 对象才能使其工作。

        【讨论】:

        • (我没有对你投反对票)也许是因为 NSKeyedUnarchiver 没有映射到 NSUserDefaults...
        • 为什么NSUserDefaults会涉及到这个概念
        • 当您不需要 UserDefaults 时,不要使用 UserDefaults。问题是关于将 NSObject 转换为 NSData。不需要保存偏好或任何持久性。
        【解决方案4】:

        您只能归档支持NSCoding 协议的对象

        【讨论】:

          【解决方案5】:

          您可以使用 NSCoding 协议将任何对象转换为 NSData。

          您可以在此处找到执行此操作的示例代码:
          http://samsoff.es/posts/archiving-objective-c-objects-with-nscoding

          【讨论】:

            【解决方案6】:

            这是一个自定义对象转换为 NSData 的示例(因此可以将其保存为用户默认值)

            创建以下文件:

            目录.h

            @interface Catalog : NSObject
            
            @property (nonatomic, assign) int pk;
            @property (nonatomic, copy) NSString *catalogName;
            @property (nonatomic, copy) NSString *catalogDescription;
            @property (nonatomic, assign) int catalogEdition;
            @property (nonatomic, assign) int catalogTotalPages;
            
            - (void)encodeWithCoder:(NSCoder *)aCoder;
            - (id)initWithCoder:(NSCoder *)aDecoder;
            
            @end
            

            目录.m

            #import <Foundation/Foundation.h>
            #import "Catalog.h"
            
            @implementation Catalog
            
            - (void)encodeWithCoder:(NSCoder *)aCoder {
                [aCoder encodeObject:self.catalogName forKey:@"catalogName"];
                [aCoder encodeObject:self.catalogDescription forKey:@"catalogDescription"];
                [aCoder encodeInt:self.catalogEdition forKey:@"catalogEdition"];
                [aCoder encodeInt:self.catalogTotalPages forKey:@"catalogTotalPages"];
            }
            
            - (id)initWithCoder:(NSCoder *)aDecoder
            {
                if (self = [super init]) {
                    self.catalogName = [aDecoder decodeObjectForKey:@"catalogName"];
                    self.catalogDescription = [aDecoder decodeObjectForKey:@"catalogDescription"];
                    self.catalogEdition = [aDecoder decodeIntForKey:@"catalogEdition"];
                    self.catalogTotalPages = [aDecoder decodeIntForKey:@"catalogTotalPages"];
                }
                return self;
            }
            
            @end
            

            最后在你的控制器中包含头文件

            #import "Catalog.h"
            

            并添加此代码以使用您的对象(在这种情况下,我保存到用户默认值中)

                        Catalog *catalog = [[Catalog alloc] init];
                        catalog.catalogName = @"catalogName";
                        catalog.catalogDescription = @"catalogName";
                        catalog.catalogEdition = 1;
            

            注意:在这行代码中是实际数据传递发生的地方

            //archiving object to nsdata
            NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:catalog];
            
            [[NSUserDefaults standardUserDefaults] setObject:encodedObject forKey:@"keyName"];
            [[NSUserDefaults standardUserDefaults] synchronize];
            

            如果你想从 NSData 取回你的对象

            NSData *nsData = [[NSUserDefaults standardUserDefaults] objectForKey:@"keyName"];
            //unarchiving object to nsdata
            Catalog *selectedCatalog = [NSKeyedUnarchiver unarchiveObjectWithData: nsData];
            

            希望这会有所帮助!

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-07-17
              • 2011-09-01
              • 2012-07-28
              相关资源
              最近更新 更多