将 Plist(NSString)解析成 NSDictionary

26

我有一个以plist结构组织的字符串,该字符串是动态获取到的(不是来自文件系统)。我该如何将该字符串转换为NSDictionary。

我尝试使用NSPropertyListSerialization将其转换为NSData,然后再转换为NSDictionary,但是当我尝试访问NSDictionary时,它返回了"[NSCFString objectAtIndex:]: unrecognized selector sent to instance 0x100539f40",这表明我的Dictionary未成功创建。

NSString示例(即plist数据):

<?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"> 
<dict> 
 <key>Key1</key> 
 <dict> 
  <key>Test1</key> 
  <false/> 
  <key>Key2</key> 
  <string>Value2</string> 
  <key>Key3</key> 
  <string>value3</string> 
 </dict> 
</dict> 
</plist> 

谢谢!

3个回答

75

请参见序列化属性列表

NSData* plistData = [source dataUsingEncoding:NSUTF8StringEncoding];
NSString *error;
NSPropertyListFormat format;
NSDictionary* plist = [NSPropertyListSerialization propertyListWithData:plistData mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&error];
NSLog( @"plist is %@", plist );
if(!plist){
    NSLog(@"Error: %@",error);
    [error release];
}

4
你的解决方案看起来非常优秀 — 使用不可变对象创建NSDictionary以及在发生错误时记得释放错误,这些都值得额外的赞扬。 :-) - Quinn Taylor
我差点称之为过度释放。哇,那个API完全违反了内存管理规则,要求调用者释放错误字符串。 - Peter Hosey
根据发布说明,Leopard中已更改以避免该违规行为。值得注意。这方面有一个错误报告:http://openradar.appspot.com/5563963 - Peter Hosey
Ahruman:我的意思是你的代码现在会泄漏,但你不需要进行版本检查,因为只有10.5的预发布版本才会为你发布错误字符串。请阅读更新后的发行说明中的“NSPropertyListSerialization(自2007年WWDC以来已更新)”部分:http://developer.apple.com/releasenotes/Cocoa/Foundation.html - Michael Tsai
19
此方法已被弃用,建议使用propertyListWithData:options:format:error:代替。 - Rafael Bugajewski
显示剩余6条评论

13

试试这个:

NSData * data = [yourString dataUsingEncoding:NSUTF8StringEncoding];

NSString *errorDesc = nil;
NSPropertyListFormat format;
NSDictionary * dict = (NSDictionary*)[NSPropertyListSerialization
                                      propertyListFromData:data
                                      mutabilityOption:NSPropertyListMutableContainersAndLeaves
                                      format:&format
                                      errorDescription:&errorDesc];

除了内存泄漏,但这种事情时有发生的 (: - Jay
NSDictionary *dict = (NSDictionary *)[NSPropertyListSerialization ...... 您需要检查您正在尝试读取的文件,因为您可能会返回NSArray而不是NSDictionary。 - Komposr

1
我曾尝试将其转换为NSData,然后使用NSPropertyListSerialization将其转换为NSDictionary,但是当我尝试访问NSDictionary时,它返回了"[NSCFString objectAtIndex:]: unrecognized selector sent to instance 0x100539f40",这表明我的Dictionary创建不成功。 不,这并没有表明任何东西。它表明您尝试将字符串视为数组。您需要确定在plist中您正在尝试获取数组的位置以及为什么在您期望一个数组的地方有一个字符串-即,是否错误地创建了plist(在其中“放入”字符串而不是预期放入数组)或错误地检查了它(存在字符串是正确的;您随后对数组的期望是错误的)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接