Что лучший способ состоит в том, чтобы сохранить и получить многомерный NSMutableArrays?

Я храню набор данных в .plist файле (в папке документов приложения), и это структурировано как это:

Dictionary {
    "description" = "String Value",
    "sections" = Array (
        Array (
            Number,
            ...
            Number
        ),
        Array (
            Number,
            ...
            Number
        )
    ),
    "items" = Array (
        Array (
            Number,
            ...
            Number
        ),
        Array (
            Number,
            ...
            Number
        )
    )
}

Если я просто получаю его с
NSMutableDictionary *d = [[NSMutableDictionary alloc] initWithContentsOfFile:plistFile] Я не смогу заменить объекты числа, корректные? Таким образом, я рекурсивно вызываю через данные прямо сейчас и формирую изменяемую версию из всего этого, и они работали в одном экземпляре, но теперь они говорят мне mutating method sent to immutable object когда все это изменяемо.

Существует ли более легкий/лучше способ сделать это? Если это имеет значение, мои данные являются просто целыми числами и булевскими переменными.

5
задан kbanman 26 January 2010 в 00:56
поделиться

3 ответа

Вместо того, чтобы писать все таможенные классы, вы должны использовать NSPROPERTILISERIZATION . В частности, см. В PropertyListwithData: Опции: Формат: Ошибка: Метод. Пример использования:

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

Это сделает все контейнеры MiCable, но сохраняют узелки листьев (например, NSStrings). Существует также возможность сделать листья смешанными тоже.

9
ответ дан 18 December 2019 в 09:07
поделиться

Я обычно упрощает создание одного или нескольких пользовательских классов для обработки загрузки и сохранения. Это позволяет конвертировать массивы в Mutablearrays явно:

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;

с тем, что сделано, вы можете инкапсулировать все код упаковки и распакования в вашем LoadFromFile и SaveToFile Методы. Основная выгода этого подхода заключается в том, что ваша основная программа становится намного проще, и она позволяет получить доступ к элементам вашей структуры данных в качестве свойств:

MyThing * thing = [[MyThing alloc] init];
[thing loadFromFile:@"..."];
...
thing.description = @"new description";
[thing.sections addObject:someObject];
[thing.items removeObjectAtIndex:4];
...
[thing saveToFile:@"..."];
[thing release];
8
ответ дан 18 December 2019 в 09:07
поделиться

То, что вы хотите, это глубокая смежная копия. Какао не включает способ сделать это. Несколько человек написали такие реализации в глубокой копии до ( пример ).

Тем не менее, основной фонд включает в себя CFPROPERTYLIST API , который имеет поддержку как для создания глубоких смежных копий объектов объектов свойств, а также считывания в списках свойств от диска в качестве изменяемых данных. (И, конечно же, типы списков недвижимости основных фондов являются бесплатные модифицированные с какао, что означает, что вам не нужно преобразовывать между ними - NSARRAY - это CFARRAY и VICE-VERSA.)

1
ответ дан 18 December 2019 в 09:07
поделиться