将 NSObject 转换为 NSData

Posted

技术标签:

【中文标题】将 NSObject 转换为 NSData【英文标题】:Converting a NSObject into 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 中提取字节。

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

等待您的回复...

【问题讨论】:

【参考方案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];

希望这会有所帮助!

【讨论】:

以上是关于将 NSObject 转换为 NSData的主要内容,如果未能解决你的问题,请参考以下文章

将 ManagedObject 转换为 NSObject

无法将类型 [NSObject : AnyObject] 转换为字符串

使用 Monotouch 时如何将 CGColor 转换为 NSObject?

无法将“对象”表达式转换为类型“MonoTouch.Foundation.NSObject”

如何将 NSObject 模型类转换为 NSManagedObject 的子类?

无法将类型“NSMutableDictionary”的值转换为强制类型“[NSObject: AnyObject]”以用于 google ios Analytics