Persisting Custom Objects

后端 未结 2 1574
时光说笑
时光说笑 2021-01-30 04:45

I have a custom object that simply inherits from NSObject. It has 3 members - two floats and an NSDate.

My app is going to have an array with a number of th

相关标签:
2条回答
  • 2021-01-30 05:28

    If you're going to want to retrieve a subset of the objects, SQLite is by far your best choice.

    If not, it's a choice between plist format and NSCoding. plist requires you to be able to convert your custom objects into something plist-friendly and then convert the plist back into your objects, but NSCoding is a little harder to wrap your head around and can't be easily edited (or examined) by hand.

    0 讨论(0)
  • 2021-01-30 05:32

    NSCoding will do exactly what you want. I recommend you read up on it in the Apple docs, but I thought it was pretty straightforward to use. Your class (and any child classes) will need to implement the NSCoding protocol and you'll need to add -encodeWithCoder: and -initWithCoder: methods to your objects. Most of the common framework classes implement NSCoding already.

    The code for your class will look something like this:

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

    It's recommended you add a version number when encoding to give you flexibility to manage changes to your archive format in future versions.

    In my class, I added a convenience method to archive my object:

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

    and another one to unarchive or create a new object:

    +(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;
    }
    

    Since your top level object is an NSArray, you'll need to modify the last two methods for your case, but most of the boilerplate code will be the same.

    0 讨论(0)
提交回复
热议问题