Как использовать arrayWithContentsOfFile для загрузки файла, успешно записанного с помощью writeToFile в ObjectiveC/XCode
Я сохраняю массив пользовательских объектов в файл списка plist следующим образом:
+(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;
}
Ничего не рушится, но каждый раз я возвращаю NSMutableArray
нулевого размера (и этот оператор регистрации подтверждает, что plant_dicts
имеет нулевой размер).
Что я делаю не так? Все подобные проблемы, которые я вижу с arrayWithContentsOfFile:
, - это люди, создающие plist вручную или с помощью редактора...Я бы подумал, что делаю это из кода. у него самого не было бы таких проблем...
Edit: я подтвердил, что больше не получаю результат нулевого размера (что странно, в этом разделе не было никаких изменений кода с момента первоначального сообщения). Однако я все еще не загружаю вещи правильно. Вот мои методы фромдикта и тодикта.
Проблема в том, что строка "shape", похоже, не загружается правильно. По крайней мере, когда я спрашиваю, есть ли shape == @"Circle", я получаю, что это не так, даже если это явно происходит в операторе NSLog. Я делаю идентичное сравнение в другом месте кода (при проверке того, как визуализировать объект), и там оно работает нормально (поэтому я предполагаю, что нет никаких странных == vs .равно как и в Java).
Двойное редактирование: подождите, нет [shape isEqualToString: @"Circle"]....почему мне не нужно было использовать его раньше, смущает меня, но добавление его здесь помогает.
2 ответа:
С помощью 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: 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)
Эта строка:
NSMutableDictionary* dict = [plant_dicts objectAtIndex: i];
Возвращает не изменяемый словарь, а неизменяемый.
Если вы хотите, чтобы он был изменяемым, вы должны сделать что-то в этом роде:
MutableDictionary* dict = [NSMutableDictionary dictionaryWithDictionary: [plant_dicts objectAtIndex: i]];