繁体   English   中英

我应该使用 NSUserDefaults 还是 plist 来存储数据?

[英]Should I use NSUserDefaults or a plist to store data?

我将存储一些字符串(可能是 10-20)。 我不确定是否应该使用 NSUserDefaults 来保存它们,或者将它们写到 plist 中。 什么被认为是最佳实践? NSUserDefaults 似乎代码行数更少,因此实现起来更快。

我想补充一点,这些字符串值将由用户添加/删除。

我假设一个数组,但它也适用于字典。

Userdefaults、Core Data 和 Plists 都可以读/写,但是如果你使用 plist,你需要注意你把它放在什么目录中。 请参阅下面的 plist 部分。

Core Data 我认为这太过分了,它只是字符串。 当您想要持久化更复杂的对象时,应该使用它。

NSUserDefaults

尽管它应该只存储用户设置,但它非常快速且易于操作。 要将它们写入用户默认值:

NSArray *stringsArray = [[NSArray alloc] arrayWithObjects: string1, string2, string3, nil];
[[NSUserDefaults standardUserDefaults] setObject:stringsArray forKey:@"MyStrings"];
[[NSUserDefaults standardUserDefaults] synchronize];

从 userdefaults 读取:

NSArray *stringsArray = [[NSUserDefaults standardUserDefaults] objectForKey:@"MyStrings"];

列表

如果要修改您的字符串,您将需要编写和读取 plist,但您不能写入应用程序的资源。

  1. 要有一个读/写 plist 首先找到文档目录

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *stringsPlistPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Strings.plist"];
  2. 创建数组(我假设字符串是 string1,...)

     NSArray *stringsArray = [[NSArray alloc] arrayWithObjects: string1, string2, string3, nil];
  3. 将其写入文件

    [stringsArray writeToFile:stringsPlistPath atomically:YES];

要阅读 plist:

  1. 找到文档目录

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *stringsPlistPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Strings.plist"];
  2. 阅读它:

     NSArray *stringsArray = [NSArray arrayWithContentsOfFile:stringsPlistPath];

iOS 最终将所有NSUserDefaults数据存储到一个 plist 文件中。 因此,如果这是您关心的问题,它不会影响性能。 我个人更喜欢将NSUserDefaults用于小数据,将 plist 用于相对较大的数据集。

注意:永远不要在NSUserDefaults中存储任何敏感信息,因为任何人都可以看到这些数据。

如果您要存储 10-20 个字符串并且正在寻找不多的代码行,那么核心数据肯定会产生过多的开销。 我建议使用 plist。 代码不多:

NSURL *plistURL = [[NSBundle mainBundle] URLForResource:@"MyStrings" withExtension:@"plist"];
NSArray *stringArray = [NSArray arrayWithContentsOfURL:plistURL];

NSUserDefaults 会将用户首选项存储到 Library/Preferences 文件夹中的文件中。 从理论上讲,它仅用于存储一些应用程序/用户属性。

Plist 文件对于管理单个文件很有用。 如果你需要管理更多,你应该使用 Coredata。 plist 文件的大小没有限制。 否则你必须小心 plist 文件,因为当你需要保存或读取它时,文件的全部内容将被加载到 memory 中。

如果字符串不仅仅是可以在 NSUserDefaults 中使用 go 的用户设置,则使用 plist 是存储字符串的不错选择。 如前所述,使用 plist 时,您必须将 plist 存储在 Documents 目录中才能写入,因为您无法写入自己应用程序的资源。 当我第一次了解到这一点时,我不清楚您自己的应用程序的 Bundle 目录与 Documents 目录的位置,所以我想我会在这里发布示例代码,首先复制一个名为“Strings.plist”的 plist(即您已经在自己的应用程序的 Bundle 目录中)复制到 Documents 目录,然后对其进行写入和读取。

// Make a path to the plist in the Documents directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *stringsPlistPathIndDoc = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Strings.plist"];

// Make a path to the plist in your app's Bundle directory
NSString *stringsPlistPathInBundle = [[NSBundle mainBundle] pathForResource:@"Strings" ofType:@".plist"];

NSFileManager *fileManager = [NSFileManager defaultManager];

// Check first that you haven't already copied this plist to the Documents directory
if (![fileManager fileExistsAtPath:stringsPlistPathIndDoc])
{
    NSError *error;

    // Copy the plist from the Bundle directory to the Documents directory 
    [fileManager copyItemAtPath:stringsPlistPathInBundle toPath:stringsPlistPathIndDoc error:&error];
}

// Write your array out to the plist in the Documents directory
NSMutableArray *stringsArray = [[NSMutableArray alloc] initWithObjects:@"string1", @"string2", @"string3", nil]; 
[stringsArray writeToFile:stringsPlistPathIndDoc atomically:YES];

// Later if you want to read it:
stringsArray = [[NSMutableArray alloc] initWithContentsOfFile:stringsPlistPathIndDoc];

使用.plist

  1. 使用 Xcode 创建一个 plist

将值写入 plist

NSURL *plistURL = [[NSBundle mainBundle] URLForResource:@"settings" withExtension:@"plist"];

 NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfURL:plistURL];
 [dict setValue:@"value" forKey:@"key"];
 [dict writeToURL:plistURL atomically:YES];

从 plist 中读取一个值

NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfURL:plistURL];
NSString *myValue = [dict valueForKey:@"key"];

NSUSerDefaults实现起来确实很快,但主要是随着你的应用程序的增长,你想要存储的越来越多,我直接去了 plist 文件。

大多数情况下,人们想要存储一些东西的列表,所以这里是我关于如何使用 NSDictionary 做到这一点的分享。 这不需要你先创建一个plist文件,它会在第一次创建保存一些东西

xcode 7 测试版,Swift 2.0

保存

func SaveItemFavorites(items : Array<ItemFavorite>) -> Bool
{
    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
    let docuDir = paths.firstObject as! String
    let path = docuDir.stringByAppendingPathComponent(ItemFavoritesFilePath)
    let filemanager = NSFileManager.defaultManager()

    let array = NSMutableArray()        

    for var i = 0 ; i < items.count ; i++
    {
        let dict = NSMutableDictionary()
        let ItemCode = items[i].ItemCode as NSString

        dict.setObject(ItemCode, forKey: "ItemCode")
        //add any aditional..
        array[i] = dict
    }

    let favoritesDictionary = NSDictionary(object: array, forKey: "favorites")
    //check if file exists
    if(!filemanager.fileExistsAtPath(path))
    {
        let created = filemanager.createFileAtPath(path, contents: nil, attributes: nil)
         if(created)
         {
             let succeeded = favoritesDictionary.writeToFile(path, atomically: true)
             return succeeded
         }
         return false
    }
    else
    {
        let succeeded = notificationDictionary.writeToFile(path, atomically: true)
        return succeeded
    }
}

文档中的小注释:

NSDictionary.writeToFile(path:atomically:)

此方法在写出文件之前递归地验证所有包含的对象都是属性列表对象( NSDataNSDateNSNumberNSStringNSArrayNSDictionary的实例),如果所有对象都不是属性列表对象,则返回 NO,因为结果文件不是有效的属性列表。

因此,无论您在dict.SetObject()设置什么,都应该是上述类型之一。

加载

private let ItemFavoritesFilePath = "ItemFavorites.plist"

func LoadItemFavorites() -> Array<ItemFavorite>
{
    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
    let docuDir = paths.firstObject as! String
    let path = docuDir.stringByAppendingPathComponent(ItemFavoritesFilePath)
    let dict = NSDictionary(contentsOfFile: path)
    let dictitems : AnyObject? = dict?.objectForKey("favorites")

    var favoriteItemsList = Array<ItemFavorite>()

    if let arrayitems = dictitems as? NSArray
    {
        for var i = 0;i<arrayitems.count;i++
        {
            if let itemDict = arrayitems[i] as? NSDictionary
            {
                let ItemCode = itemDict.objectForKey("ItemCode") as? String
                //get any additional

                let ItemFavorite = ItemFavorite(item: ItemCode)
                favoriteItemsList.append(ItemFavorite)
            }
        }
    }

    return favoriteItemsList
}

这取决于您要存储的内容以及原因。 NSUserDefaults 用于存储用户偏好。 您可以尝试将其用于其他事情,但您可能不应该这样做。

否则,如果您的需求很简单,则 plist 文件非常简单。 您还可以使用核心数据或提出自己的文件格式。 一般来说,我将 plist 用于简单的任务,然后转移到核心数据来处理更复杂的任务。

像这样持久化数据的推荐方法是使用 Core Data。 虽然 NSUserDefaults 可用于存储或多或少的任何内容,但它只应该用于存储首选项。

暂无
暂无

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

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