10

我有一个简单地从 NSObject 继承的自定义对象。它有 3 个成员 - 两个浮点数和一个NSDate.

我的应用程序将有一个数组,其中包含许多这样的对象,我需要在运行之间保持它。我怎样才能做到这一点?

我曾考虑过使用 SQLite 数据库,但我认为这有点矫枉过正,因为我曾经做过的唯一查询是select *.

在理想的世界中,我想使用 xml plist 文件。我不确定我是否可以用我的自定义对象来做到这一点。我知道有一组 Property List 对象,NSArray属于它,但writeToFile:atomically:仅适用于 property list 对象。

任何想法将不胜感激,谢谢!

4

2 回答 2

21

NSCoding会做你想做的事。我建议您在 Apple 文档中阅读它,但我认为它使用起来非常简单。您的类(和任何子类)将需要实现NSCoding协议,并且您需要向对象添加-encodeWithCoder:-initWithCoder:方法。大多数常见的框架类NSCoding已经实现。

您的课程的代码将如下所示:

-(void) encodeWithCoder: (NSCoder*) coder {
  [coder encodeInteger: versionValue forKey: versionKey];
  [coder encodeObject: myStuff forKey: myStuffKey];
}

-(id) initWithCoder: (NSCoder*) coder {
  self = [super init];
  if ( ! self) return nil;
  myStuff = [[coder decodeObjectForKey: myStuffKey] retain];
  return self;
}

建议您在编码时添加一个版本号,以便您在未来版本中灵活地管理对存档格式的更改。

在我的课堂上,我添加了一个方便的方法来归档我的对象:

-(void) archiveToFile: (NSString*) path {
  NSMutableData *data = [[NSMutableData alloc] init];
  NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData: data];
  [archiver encodeObject: self forKey: myArchiveKey];
  [archiver finishEncoding];
  [archiver release];
  [data writeToFile: path atomically: YES];
  [data release];
}

另一个用于取消归档或创建新对象:

+(MyArchive*) newFromFile: (NSString*) path
            orWithMyStuff: (MyStuff*) myStuff
{
  NSData *data = [[NSData alloc] initWithContentsOfFile: path];
  NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData: data];
  MyArchive *myArchive = [unarchiver decodeObjectForKey: myArchiveKey];
  [unarchiver finishDecoding];

  if (myArchive) {
    [myArchive retain];
  } else {
    myArchive = [[MyArchive alloc] initWithStuff: myStuff;
  }
  [unarchiver release];
  [data release];
  return myArchive;
}

由于您的顶级对象是NSArray,因此您需要针对您的案例修改最后两个方法,但大多数样板代码都是相同的。

于 2009-03-15T19:58:42.913 回答
0

如果您要检索对象的子集,SQLite 是迄今为止您的最佳选择。

如果不是,则在 plist 格式和 NSCoding 之间进行选择。plist 要求您能够将自定义对象转换为 plist 友好的对象,然后将 plist 转换回您的对象,但是 NSCoding 有点难以绕开您的头,并且不能轻松地手动编辑(或检查) .

于 2009-03-15T18:41:25.923 回答