Plist Array для NSDictionary - PullRequest
       17

Plist Array для NSDictionary

11 голосов
/ 27 августа 2009

У меня есть листинг:

<plist version="1.0">
  <array>
    <dict>
      <key>name</key>
      <string>Alabama</string>
      <key>abreviation</key>
      <string>AL</string>
      <key>date</key>
      <string>1819</string>
      <key>population</key>
      <string>4,627,851</string>
      <key>capital</key>
      <string>Montgomery</string>
      <key>largestCity</key>
      <string>Birmingham</string>
    </dict>
    <dict>
      <key>name</key>
      <string>Alaska</string>
      <key>abreviation</key>
      <string>AK</string>
      <key>date</key>
      <string>1959</string>
      <key>population</key>
      <string>683,478</string>
      <key>capital</key>
      <string>Juneau</string>
      <key>largestCity</key>
      <string>Anchorage</string>
    </dict>
    ...
  </array>
</plist>

Я пытаюсь загрузить его в NSDictionary так:

NSString *path = [[NSBundle mainBundle] pathForResource:@"stateInfo" ofType:@"plist"];

NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:path]) {
    NSLog(@"The file exists");
} else {
    NSLog(@"The file does not exist");
}

NSMutableDictionary *myDic = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
//NSDictionary *myDic = [NSDictionary dictionaryWithContentsOfFile:path];
NSLog(@"The count: %i", [myDic count]);

NSArray *thisArray = [[NSArray alloc] initWithContentsOfFile:path];
NSLog(@"The array count: %i", [thisArray count]);

Я всегда получаю количество массивов, равное 50, но словарь равен нулю. Поэтому я попытался перебрать массив и добавить его в словарь:

NSDictionary *eachState;
for (eachState in thisArray) {
    State *thisState = [[State alloc] initWithDictionary:eachState];
    [myDic setObject:thisState forKey:thisState.name];
}

Но цикл вызывает исключение:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '*** -[NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'

State - это класс со свойствами, соответствующими моему списку. Что я делаю неправильно? Я вижу здесь много разных вопросов, но не могу их получить.

Ответы [ 2 ]

17 голосов
/ 27 августа 2009

Две проблемы:

  • Загрузка списка в NSDictionary:

Это простая проблема, которую вы, похоже, уже поняли. Глобальный объект в вашем списке является массивом, а не диктатом, поэтому, когда вы загружаете его в словарь, он не знает, что делать (несовместимые типы), поэтому вы получаете пустой словарь.

  • Цикл по массиву словарей:

Из полученного исключения вы вызываете 'setObject: forKey:' в словаре, который инициализируется как NSDictionary, а не NSMutableDictionary. Указатель напечатан как NSMutableDictionary, но не фактический в памяти объекта. Вам нужно изменить свою линию с.

NSMutableDictionary *myDic = [[NSDictionary alloc] initWithContentsOfFile:path];

до

NSMutableDictionary *myDic = [[NSMutableDictionary alloc] initWithContentsOfFile:path];

и фактически, поскольку загрузка словаря из файла дает вам пустой словарь, вы тратите впустую циклы, пытаясь загрузить его из файла, и должны просто создать новый:

NSMutableDictionary *myDic = [[NSMutableDictionary alloc] init];
10 голосов
/ 29 августа 2009

Более гибкий способ загрузки списков в память, который также позволяет создавать изменяемые списки:

NSData* data = [NSData dataWithContentsOfFile:path];
NSMutableArray* plist = [NSPropertyListSerialization propertyListFromData:data
                                                         mutabilityOption:NSPropertyListImmutable
                                                                   format:NSPropertyListXMLFormat_v1_0
                                                         errorDescription:NULL];

Таким образом, ваш код может быть реализован как:

NSString *path = [[NSBundle mainBundle] pathForResource:@"stateInfo" ofType:@"plist"];
NSData* data = [NSData dataWithContentsOfFile:path];
NSMutableArray* array = [NSPropertyListSerialization propertyListFromData:data
                                                         mutabilityOption:NSPropertyListImmutable
                                                                   format:NSPropertyListXMLFormat_v1_0
                                                         errorDescription:NULL];
if (array) {
  NSMutableDictionary* myDict = [NSMutableDictionary dictionaryWithCapacity:[array count]];
  for (NSDictionary* dict in array) {
    State* state = [[State alloc] initWithDictionary:dict];
    [myDict setObject:state forKey:state.name;
    [state release];
  }
  NSLog(@"The count: %i", [myDic count]);
} else {
  NSLog(@"Plist does not exist");
}
...