Persisting Custom Objects

后端 未结 2 1593
时光说笑
时光说笑 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: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.

提交回复
热议问题