【问题标题】:How do I store a string as an array in a Cocoa property list?如何将字符串作为数组存储在 Cocoa 属性列表中?
【发布时间】:2010-11-01 15:18:13
【问题描述】:

我正在尝试保存两个字符串。一个字符串需要在 pList 中保存为 ARRAY 类型,第二个字符串需要在 Array 中保存为 String。

我可以使用代码:

[字典 setObject:(id)anObject forKey:(id)aKey>]

但它没有正确保存它。我可以将其中一个字符串转换为数组,但它仍然无法正常工作。

将数组保存到 pList 的正确方法是什么?

这是我的 pList 的样子:

<dict>
<key>Test One</key>
<array>
    <string>A13#</string>
</array>
<key>Another Test</key>
<array>
    <string>1111111111</string>
</array>
<key>Test Three</key>
<array>
    <string>2222222222</string>
</array>
<key>Final Test</key>
<array>
    <string>3333333333</string>
</array>
</dict>

这是我尝试使用的方法

-(void)writeToFile:(NSString *)s1{
    NSBundle *bundle = [NSBundle mainBundle];
NSString *plistPath = [bundle pathForResource:@"saved" ofType:@"plist"];

NSMutableDictionary *dictionary = [[[NSDictionary alloc] initWithContentsOfFile:plistPath] mutableCopy];
NSString *tempString = [NSString stringWithFormat:@"1234567"];
[dictionary setObject:tempString forKey:s1];

[dictionary writeToFile:plistPath atomically:YES];
}

【问题讨论】:

  • 将字符串保存为数组是什么意思?

标签: iphone objective-c plist ipod-touch


【解决方案1】:

您不能将字符串转换或以其他方式转换为数组;它们是独立的、不同的对象。就像在现实生活中你试图把你的狗变成一辆旅行车一样,它没有发生。

相反,将您的狗放在旅行车内(或将您的绳子放在一个数组中)。您可以使用[NSArray arrayWithObjects:@"string1", @"string2", nil]; 创建数组。将给定键的值粘贴到字典中,以及另一个键的最终字符串,保存它,您将拥有一个包含一个或多个字符串数组的 plist。

另外,在您的代码示例中,您的字典正在泄漏内存。阅读 Objective-C 中的内存管理,你会遇到很多崩溃和性能问题,直到你完全理解它。

【讨论】:

  • 事实上,你不能将任何对象从一个类转换到另一个类。
  • 不正确,如果您要转换的对象实际上可以像要转换到的类一样运行,则可以。例如,假设您有一个 NSMutableArray 对象存储在 NSArray* array 指针中。如果您尝试对其调用-removeLastObject,编译器将使用静态类型并通知您NSArray 不会响应该消息。但是,您可以做到[(NSMutableArray*)array removeLastObject] just fine. You'll run into problems if array`实际上是一个NSArray,或者如果您将存储在id变量中的对象转换为不兼容的类,例如将字符串转换为数组。
【解决方案2】:

您可以使用

将字符串转换为单个元素数组
[NSArray arrayWithObject:str];

因此,如果您希望您的 plist 包含作为字符串数组的条目,并且您只想要一个字符串作为元素,那么您可以执行以下操作:

[dictionary setObject:[NSArray arrayWithObject:tempString] forKey:s1];

我真的不知道为什么你会想要这种方式,除非你想在其他时间允许每个键有多个字符串。

此外,正如 Marc 所提到的,您正在泄漏您创建的初始(不可变)说明。在http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html阅读内存管理规则。

此外,您永远不应该在应用程序的包中编写代码。一方面,您的应用程序可能位于写保护卷上,或者当前用户可能无权更改它。另一方面,该文件将由所有用户共享。第三,它会破坏代码签名。而是将文件写入 Preferences 文件夹或 Application Support 文件夹。

最后,如果这些旨在成为某种用户偏好,那么您应该使用偏好系统,它允许配置默认值并将偏好存储在偏好文件夹中。请参阅http://developer.apple.com/documentation/Cocoa/Conceptual/UserDefaults/UserDefaults.html 了解更多信息。

【讨论】:

    【解决方案3】:

    NSArray(单独)保存到 plist 文件的正确方法如下:

    NSArray* anArray = ...;
    [anArray writeToFile:@"/path/to/file.plist" atomically:YES];
    

    但是,您不能将 NSString 保存为数组。鉴于您提供的 XML plist,如果您想添加具有相同格式的条目,您可以使用这个更简单的代码:

    - (void) writeToFile:(NSString *)string {
      NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"saved" ofType:@"plist"];
      NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithContentsOfFile:plistPath];
      [dictionary setObject:[NSArray arrayWithObject:@"1234567"] forKey:string];
      [dictionary writeToFile:plistPath atomically:YES];
    }
    

    这也避免了代码中的内存泄漏,其中-mutableCopy 的接收者以保留计数 1 转义。(这在 GC 下不是问题,但它仍然是不好的做法。)你不应该需要要使用+[NSString stringWithFormat:],只需使用字符串文字。如果你想在数组中使用不同的字符串,你可以将它作为附加参数传入,从另一个方法中获取,等等。

    这个方法仍然很脆弱,因为它只在数组中存储一个与给定键匹配的字符串——而且,如果方法名称能更准确地说明它的作用,它会更好。此外,如果每个键只有一个字符串值,您可能会考虑修改 plist 以完全省略数组,因为它只会占用空间并使代码复杂化。

    【讨论】:

    • 注意,在这种情况下,虽然 +dictionaryWithContentsOfFile 是 NSDictionary 上的便利构造函数,但它是由 NSMutableDictionary 继承的,并且会返回一个接收者类的实例。这适用于 Foundation 中的其他可变/不可变类,例如 NS(Mutable)String、NS(Mutable)Array 等。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 2015-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-16
    • 2021-09-05
    相关资源
    最近更新 更多