What's the best way to store and retrieve multi-dimensional NSMutableArrays?

前端 未结 3 807
挽巷
挽巷 2021-02-10 04:45

I\'m storing a bunch of data in a .plist file (in the application documents folder), and it\'s structured like this:

Dictionary {
    \"description\" = \"String          


        
相关标签:
3条回答
  • 2021-02-10 05:13

    Instead of writing all that custom class junk, you should use NSPropertyListSerialization. Specifically, see the propertyListWithData:options:format:error: method. Example usage:

    NSMutableDictionary *d = [NSPropertyListSerialization propertyListWithData:[NSData dataWithContentsOfFile:@"path/to/file"] 
                                                                       options:NSPropertyListMutableContainers
                                                                        format:NULL
                                                                         error:NULL];
    

    This will make all the containers mutable, but keep the leaf nodes (e.g. NSStrings) immutable. There's also an option to make the leaves mutable too.

    0 讨论(0)
  • 2021-02-10 05:13

    What you want is a deep mutable copy. Cocoa doesn't include a way to do it. A few people have written such deep-copy implementations before (example).

    However, Core Foundation includes the CFPropertyList API, which does have support both for creating deep mutable copies of property list objects as well as reading in property lists from disk as mutable datatypes. (And, of course, Core Foundation's property list types are toll-free bridged with Cocoa's, meaning you don't have to convert between them — an NSArray is a CFArray and vice-versa.)

    0 讨论(0)
  • 2021-02-10 05:19

    I usually find it easier to create one or more custom classes to handle loading and saving. This lets you convert the arrays to mutableArrays explicitly:

    MyThing.h

    @interface MyThing : NSObject
    {
        NSString * description;
        NSMutableArray * sections;
        NSMutableArray * items;
    }
    @property (copy) NSString * description;
    @property (readonly) NSMutableArray * sections;
    @property (readonly) NSMutableArray * items;
    - (void)loadFromFile:(NSString *)path;
    - (void)saveToFile:(NSString *)path;
    @end
    

    MyThing.m

    @implementation MyThing
    @synthesize description;
    @synthesize sections
    @synthesize items;
    
    - (id)init {
        if ((self = [super init]) == nil) { return nil; }
        sections = [[NSMutableArray alloc] initWithCapacity:0];
        items = [[NSMutableArray alloc] initWithCapacity:0];
        return self;
    }
    
    - (void)dealloc {
        [items release];
        [sections release];
    }
    
    - (void)loadFromFile:(NSString *)path {
        NSDictionary * dict = [NSDictionary dictionaryWithContentsOfFile:path];
        [self setDescription:[dict objectForKey:@"description"]];
        [sections removeAllObjects];
        [sections addObjectsFromArray:[dict objectForKey:@"sections"]];
        [items removeAllObjects];
        [items addObjectsFromArray:[dict objectForKey:@"items"]]; 
    }
    
    - (void)saveToFile:(NSString *)path {
        NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys:
                               description, @"description",
                               sections, @"sections",
                               items, @"items",
                               nil];
        [dict writeToFile:path atomically:YES];
    }
    
    @end;
    

    With that done, you can encapsulate all of the packaging and unpackaging code in your loadFromFile and saveToFile methods. The major benefit of this approach is that your main program gets a lot simpler, and it allows you to access the elements of your data structure as properties:

    MyThing * thing = [[MyThing alloc] init];
    [thing loadFromFile:@"..."];
    ...
    thing.description = @"new description";
    [thing.sections addObject:someObject];
    [thing.items removeObjectAtIndex:4];
    ...
    [thing saveToFile:@"..."];
    [thing release];
    
    0 讨论(0)
提交回复
热议问题