将NSObject转换为NSData

时间:2009-11-02 07:50:18

标签: iphone

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

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

NSData *dataOnObject = [NSKeyedArchiver archivedDataWithRootObject:classObject];

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

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

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

但是,它仍然给出例外。

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

非常感谢任何帮助......

等待你的回复...

6 个答案:

答案 0 :(得分:22)

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

- (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];

答案 1 :(得分:7)

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

答案 2 :(得分:6)

而不是

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对象才能工作。

答案 3 :(得分:5)

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

答案 4 :(得分:1)

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

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

答案 5 :(得分:0)

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

创建以下文件:

Catalog.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

Catalog.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];

希望这有帮助!