简体   繁体   English

Plist数组到NSDictionary

[英]Plist Array to NSDictionary

I have a plist: 我有一个plist:

<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>

I am trying to load it into an NSDictionary like this: 我试图将它加载到像这样的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]);

I always get an array count of 50 but a dictionary count of zero. 我总是得到50的数组计数,但字典数为零。 So I tried looping through the array and adding it to the dictionary: 所以我尝试循环遍历数组并将其添加到字典中:

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

But the loop is throwing an exception: 但循环抛出一个异常:

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

State is a class with properties matching my plist. State是一个属性与我的plist匹配的类。 What am I doing wrong? 我究竟做错了什么? I see all kinds of related questions out here but I can't get it. 我在这里看到了各种相关的问题,但我无法理解。

The two problems: 这两个问题:

  • Loading the plist into an NSDictionary: 将plist加载到NSDictionary中:

This is a simple problem, which it seems you have already figured out. 这是一个简单的问题,似乎你已经想到了。 The global object in your plist is an array, not a dict, so when you load it into the dictionary, it doesn't know what to do (incompatable types), so you're getting an empty dictionary. plist中的全局对象是一个数组,而不是一个dict,所以当你将它加载到字典中时,它不知道该做什么(不兼容的类型),所以你得到一个空字典。

  • Looping through the array of dictionaries: 循环遍历各种词典:

From the Exception you're getting, you are calling 'setObject:forKey:' on the dictionary, which is initialized as an NSDictionary, not an NSMutableDictionary. 从你得到的Exception,你在字典上调用'setObject:forKey:',它被初始化为NSDictionary,而不是NSMutableDictionary。 The pointer is typed as NSMutableDictionary, but not the actual in memory object. 指针的类型为NSMutableDictionary,但不是实际的内存对象。 You need to change your line from. 你需要改变你的线路。

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

to

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

and actually, since loading the dictionary from the file gives you an empty dictionary, you are wasting cycles trying to load it from the file, and should just create a new one: 实际上,因为从文件加载字典会给你一个空字典,你就是在浪费周期试图从文件中加载它,并且应该创建一个新字典:

NSMutableDictionary *myDic = [[NSMutableDictionary alloc] init];

A more flexible way to load plists into memory, that also allows you to create mutable plists: 将plist加载到内存中的一种更灵活的方法,也允许您创建可变的plist:

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

Thus your code could be implemented as: 因此,您的代码可以实现为:

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");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM