Saving Array to Plist file that contains Custom Objects iPhone

前端 未结 5 1292
猫巷女王i
猫巷女王i 2021-02-04 22:39

I have a class called XYZ inheriting from NSObject and an array which contains objects of XYZ. I need to write this array to a plist file on to documents directory. After trying

相关标签:
5条回答
  • 2021-02-04 23:12

    Conforming your XYZ class to the NSCoding protocol is indeed very suitable for what you're trying to do. To do so, add the NSCoding protocol to your class's interface declaration:

    @interface XYZ <NSCoding>
    

    Then, you need implement encodeWithCoder: and initWithCoder: in your implementation. "Encode with coder" means "take your object's current state, and pack it into a generic object called an 'encoder'". "Init with coder" means "given an already-packed encoder object, configure yourself with the data packed into the encoder". In both of these methods, the 'encoder' will be an instance of NSCoder, which has a fairly simple interface for encoding ("packing") and decoding ("unpacking") basic types.

    Here's a sample implementation:

    @implementation XYZ
    - (id)initWithCoder:(NSCoder*)encoder
    {
        self = [self init];
    
        if (self)
        {
            self.myIntProperty = [encoder decodeIntForKey:@"myInt"];
        }
    
        return self;
    }
    
    – (void)encodeWithCoder:(NSCoder*)decoder
    {
        [decoder encodeInt:self.myIntProperty forKey:@"myInt"];
    }
    
    @end
    
    0 讨论(0)
  • 2021-02-04 23:16

    There is a very good tutorial on the Ray Wenderlich's blog which explains how to work with the NSCoding.

    Simply you just have to implement the *-(void)encodeWithCoder:(NSCoder )encode and *-(id)initWithCoder:(NSCoder )decoder methods in your object that respects the NSCoding protocol like that:

    // Header
    @interface AnObject: NSObject <NSCoding>
    
    // Implementation
    - (void) encodeWithCoder:(NSCoder *)encoder {
        [encoder encodeObject:ivar1 forKey:@"ivar1"];
        [encoder encodeFloat:ivar2 forKey:@"ivar2"];
    }
    
    - (id)initWithCoder:(NSCoder *)decoder {
        self = [super initWithCoder:coder];
        ivar1 = [[coder decodeObjectForKey:@"ivar1"] retain];
        ivar2 = [[coder decodeObjectForKey:@"ivar2"] retain];
        return self;
    }
    

    You can also check the official documentation here.

    0 讨论(0)
  • 2021-02-04 23:22

    You need to implement two methods: -initWithCoder: and -encodeWithCoder:. Read the NSCoding docs; they’re pretty straight-forward methods. You basically want to encode/decode your instance variables with a key that corresponds to its name.

    0 讨论(0)
  • 2021-02-04 23:25

    After implementing encodeWithCoder: and initWithCoder: for the custom class here is how to write and read:

    Write:

    NSError  *error;
    NSData* archiveData = [NSKeyedArchiver archivedDataWithRootObject:yourClassInstance];
    [archiveData writeToFile:filePath options:NSDataWritingAtomic error:&error];
    

    Read:

    NSData *archiveData = [NSData dataWithContentsOfFile:filePath];
    YourClass *yourClassInstance = (NSArray*)[NSKeyedUnarchiver unarchiveObjectWithData:archiveData];
    
    0 讨论(0)
  • 2021-02-04 23:25

    It's pretty straight forward. For given class Foo:

    #import <Foundation/Foundation.h>
    
    @interface Foo : NSObject <NSCoding> {
        NSArray* bar_;
        NSUInteger baz_;
    }
    
    @property (nonatomic, retain) NSArray *bar;
    @property (nonatomic, assign) NSUInteger baz;
    
    @end
    

    All you have to do to conform to the NSCoding protocol is to implement the initWithCoder: and decodeWithCoder messages:

    #import "Foo.h"
    
    @implementation Foo
    @synthesize bar = bar_;
    @synthesize baz = baz_;
    
    #pragma mark - NSCoding
    
    - (void)encodeWithCoder:(NSCoder *)encoder  {
        [encoder encodeObject:self.bar forKey:@"bar"];
        [encoder encodeInteger:self.baz forKey:@"baz"];
    }
    
    - (id)initWithCoder:(NSCoder *)decoder  {
        if ((self = [super init])) {
            self.bar = [decoder decodeObjectForKey:@"bar"];
            self.baz = [decoder decodeIntegerForKey:@"baz"];
        }
        return self;
    }
    
    - (void) dealloc {
    
        [bar_ release];
        [super dealloc];    
    }
    
    @end
    
    0 讨论(0)
提交回复
热议问题