Как использовать arrayWithContentsOfFile для загрузки файла, успешно записанного с помощью writeToFile в ObjectiveC / XCode - PullRequest
6 голосов
/ 18 февраля 2012

Я сохраняю массив пользовательских объектов в файл списка рассылки, например:

+(void) arrayToPlist: (NSArray*) plant_types{
    NSMutableArray* dictionary_array = [NSMutableArray arrayWithCapacity: plant_types.count];

    for(int i = 0; i<plant_types.count; i++){
        PlantType* pt = [plant_types objectAtIndex: i];
        [dictionary_array addObject: [pt toDict]];
    }

    NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString* filePath    = [rootPath stringByAppendingPathComponent:@"PlantTypes.plist"];
    NSLog(@"Writing plist to: %@", filePath);

    [dictionary_array writeToFile: filePath atomically: YES];  
}

, который создает файл, который выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <dict>
        <key>name</key>
        <string>Autumn Olive</string>
        <key>radius</key>
        <real>10</real>
    </dict>
    <dict>
        <key>name</key>
        <string>Dwarf Cherry</string>
        <key>radius</key>
        <real>5</real>
    </dict>
    <dict>
        <key>name</key>
        <string>Bamboo</string>
        <key>radius</key>
        <real>2</real>
    </dict>
    <dict>
        <key>name</key>
        <string>Pomegranate</string>
        <key>radius</key>
        <real>6</real>
    </dict>
    <dict>
        <key>name</key>
        <string>Lupin</string>
        <key>radius</key>
        <real>0.60000002384185791</real>
    </dict>
</array>
</plist>

И загружаем их таким образом:

+(NSMutableArray*) arrayFromPlist{
    NSLog(@"Loading array of plant types from plist.");

    NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString* filePath    = [rootPath stringByAppendingPathComponent:@"PlantTypes.plist"];
    NSFileManager*  fileManager = [NSFileManager defaultManager];

    if([fileManager fileExistsAtPath:filePath]){ 
        NSLog(@"Plist file exists at expected location.");
        NSMutableArray* plant_dicts = [NSMutableArray arrayWithContentsOfFile:filePath];
        NSLog(@"Loaded array with contents of file, got %d plant types.", plant_dicts.count);
        NSMutableArray* plant_types = [NSMutableArray arrayWithCapacity: plant_dicts.count];
        for(int i = 0; i< plant_dicts.count; i++){
            NSMutableDictionary* dict = [plant_dicts objectAtIndex: i];
            [plant_types addObject: [PlantType fromDict: dict]];
        }
        return plant_types;
    }
    NSLog(@"Plant Type plist file not found.");
    return NULL;
}

Nothings аварийно завершается, но каждый раз, когда я возвращаю NSMutableArray нулевого размера (и это утверждение журнала подтверждает, что plant_dicts имеет нулевой размер).

Что я делаю не так? Все подобные проблемы, с которыми я сталкиваюсь в arrayWithContentsOfFile:, - это то, что люди создают plist вручную или с помощью редактора ... Я думаю, что создание этого кода из самого кода не будет иметь таких проблем ...

Редактировать: Я подтвердил, что больше не получаю результат нулевого размера (что странно, с тех пор как в исходном посте не было никаких изменений кода в этом разделе). Тем не менее, я все еще не загружаю вещи правильно. Вот мои методы fromDict и toDict.

Проблема в том, что строка "shape" не загружается правильно. По крайней мере, когда я спрашиваю, есть ли shape == @ "Circle", я получаю, что это не так, даже если это ясно в заявлении NSLog. Я делаю идентичное сравнение в другом месте кода (при проверке того, как визуализировать объект), и он прекрасно работает там (так что я предполагаю, что нет некоторых странных == vs .equals, как в Java).

Двойное редактирование: Подождите, нет [shape isEqualToString: @ "Circle"] .... почему мне не нужно было использовать его, прежде чем меня смущает, но добавление здесь помогает.

Ответы [ 2 ]

5 голосов
/ 22 февраля 2012

С вашим списком этот код возвращает правильный результат

+(NSMutableArray*) arrayFromPlist{
    NSLog(@"Loading array of plant types from plist.");

    NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString* filePath    = [rootPath stringByAppendingPathComponent:@"PlantTypes.plist"];
    NSFileManager*  fileManager = [NSFileManager defaultManager];

    if([fileManager fileExistsAtPath:filePath]){ 
        NSLog(@"Plist file exists at expected location.");
        NSMutableArray* plant_dicts = [NSMutableArray arrayWithContentsOfFile:filePath];
        NSLog(@"Loaded array with contents of file, got %d plant types.", plant_dicts.count);
        NSMutableArray* plant_types = [NSMutableArray arrayWithCapacity: plant_dicts.count];
        for(int i = 0; i< plant_dicts.count; i++){
            NSMutableDictionary* dict = [plant_dicts objectAtIndex: i];
            [plant_types addObject: dict];
        }
        return plant_types;
    }
    NSLog(@"Plant Type plist file not found.");
    return NULL;
}

результат

2012-02-22 16:24:43.697 Test[5574:10103] Loading array of plant types from plist.
2012-02-22 16:24:43.698 Test[5574:10103] Plist file exists at expected location.
2012-02-22 16:24:43.699 Test[5574:10103] Loaded array with contents of file, got 5 plant types.
2012-02-22 16:24:43.700 Test[5574:10103](
        {
        name = "Autumn Olive";
        radius = 10;
    },
        {
        name = "Dwarf Cherry";
        radius = 5;
    },
        {
        name = Bamboo;
        radius = 2;
    },
        {
        name = Pomegranate;
        radius = 6;
    },
        {
        name = Lupin;
        radius = "0.6000000238418579";
    }
)

Я думаю, что проблема связана с вашей реализацией PlantType.Можете ли вы опубликовать свой код (методы toDict и fromDict)

0 голосов
/ 22 февраля 2012

Эта строка:

NSMutableDictionary* dict = [plant_dicts objectAtIndex: i];

не возвращает изменяемый словарь, но неизменный.

Если вы хотите, чтобы оно было изменчивым, вы должны сделать что-то вроде этого:

MutableDictionary* dict = [NSMutableDictionary dictionaryWithDictionary: [plant_dicts objectAtIndex: i]];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...