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

发布于 2024-11-29 10:04:25 字数 154 浏览 3 评论 0原文

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

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

I will be storing a few strings (maybe 10-20). I am not sure if I should use NSUserDefaults to save them, or write them out to a plist. What is considered best practice? NSUserDefaults seems like it is less lines of code, therefore quicker to implement.

I'd like to add that these string values will be added/removed by the user.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

梦一生花开无言 2024-12-06 10:04:25

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

Userdefaults、Core Data 和 Plist 都可以读/写,但如果您使用 plist,则需要注意放置它的目录。请参阅下面的 plist 部分。

核心数据我认为这太过分了,它只是字符串。
当您想要持久保存更复杂的对象时应该使用它。

NSUserDefaults

虽然它应该只存储用户设置,但它非常快速且易于执行。
要将它们写入 userdefaults:

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

如果要修改您的字符串,您将需要编写和读取 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 原子地:YES];
    

读取plist:

  1. 查找文档目录

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

    NSArray *stringsArray = [NSArray arrayWithContentsOfFile:stringsPlistPath];
    

I am assuming an array, but it will work with dictionaries too.

Userdefaults, Core Data and Plists can all be read/write but if you use a plist you need to pay attention in what dir you put it. See the plist part down below.

Core Data I think it's way too much overkill, it's just strings.
It's supposed to be used when you want to persist more complex objects.

NSUserDefaults:

It's pretty fast and easy to do, though it's supposed to store only user settings.
To write them to the userdefaults:

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

To read the from the userdefaults:

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

Plist:

If your strings are going to be modified you will need to write and read a plist but you cant't write into your app's resources.

  1. To have a read/write plist first find the documents directory

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *stringsPlistPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Strings.plist"];
    
  2. Create the array (I am assuming the strings are string1, ...)

    NSArray *stringsArray = [[NSArray alloc] arrayWithObjects: string1, string2, string3, nil];
    
  3. Write it to file

    [stringsArray writeToFile:stringsPlistPath atomically:YES];
    

To read the plist:

  1. Find the documents directory

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

    NSArray *stringsArray = [NSArray arrayWithContentsOfFile:stringsPlistPath];
    
子栖 2024-12-06 10:04:25

如果您要存储 10-20 个字符串并且需要的代码行数不是太多,那么核心数据的开销肯定太大了。我建议使用 plist。代码不多:

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

If you are storing 10-20 strings and are looking for not too many lines of code, core data is certainly much too much overhead. I recommend going with the plist. Not a lot of code:

NSURL *plistURL = [[NSBundle mainBundle] URLForResource:@"MyStrings" withExtension:@"plist"];
NSArray *stringArray = [NSArray arrayWithContentsOfURL:plistURL];
牛↙奶布丁 2024-12-06 10:04:25

iOS 最终将所有 NSUserDefaults 数据存储到 plist 文件中。因此,如果您担心的话,它不会影响性能。我个人更喜欢使用 NSUserDefaults 来处理小数据,使用 plist 来处理相对较大的数据集。

注意:切勿在 NSUserDefaults 中存储任何敏感信息,因为任何人都可以看到该数据。

iOS ultimately stores all NSUserDefaults data to a plist file. So it will not affect the performance if that is your concern. I personally prefer using NSUserDefaults for small data and plist for a relatively large set of data.

Note: Never store any sensitive information in NSUserDefaults as anyone can see that data.

许久 2024-12-06 10:04:25

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

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

NSUserDefaults will store the user preferences into a file into the Library/Preferences folder. In theory it serves only to store some application/user properties.

Plist file are usefull to manage a single file. If you need to manage more you should use the Coredata.
There is no restriction about the size of the plist file. Otherwise you have to be careful with plist file because when you need to save or read it the entire contents of the file will be load into memory.

月野兔 2024-12-06 10:04:25

使用 .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"];

Using .plist

  1. Create a plist using Xcode

Write a value to plist

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

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

Read a value from plist

NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfURL:plistURL];
NSString *myValue = [dict valueForKey:@"key"];
鹿港小镇 2024-12-06 10:04:25

这取决于您想要存储的内容以及原因。 NSUserDefaults 用于存储用户首选项。您可以尝试将其用于其他用途,但您可能不应该这样做。

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

It depends on what you want to store and why. NSUserDefaults is meant for storing user preferences. You can try to use it for other things, but you probably shouldn't.

Otherwise, if your needs are simple a plist file is pretty straightforward. You can also use core data or come up with your own file format. In general, I use plist for simple tasks and then move to core data for anything more complex.

尘世孤行 2024-12-06 10:04:25

如果字符串不仅仅是可以放入 NSUserDefaults 中的用户设置,那么使用 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];

Using a plist is a good choice for storing your strings if the strings are not just user settings that can go in NSUserDefaults. As was mentioned, when using a plist you must store your plist in the Documents directory in order to write to it, because you can't write into your own app's resources. When I first learned this, I wasn't clear on where your own app's Bundle directory was vs. where the Documents directory was, so I thought I'd post example code here that first copies a plist called "Strings.plist" (that you already have in your own app's Bundle directory) to the Documents directory, and then writes to it and reads from it.

// 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];
情魔剑神 2024-12-06 10:04:25

NSUSerDefaults 确实实现起来很快,但大多数情况下,随着应用程序的增长,您想要存储的数据越来越多,我直接使用 plist 文件。

大多数情况下,人们想要存储一些内容的列表,所以这里是我分享如何使用 NSDictionary 来做到这一点。这不需要您首先创建 plist 文件,它将在第一次创建时保存

xcode 7 beta、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:)

此方法递归地验证所有包含的对象是否都是属性列表对象(NSDataNSDateNSNumberNSString 的实例NSArrayNSDictionary) 在写出文件之前,如果所有对象都不是属性列表对象,则返回 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 is indeed quick to implement, but mostly as your application grows, you want to store more and more, I went directly for plist files.

Mostly, people want to store a list of something, so here is my share on how to do this with NSDictionary. This does not require you to create a plist file first, it will be created at the first time saving something

xcode 7 beta, Swift 2.0

saving

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

Little note from the docs:

NSDictionary.writeToFile(path:atomically:)

This method recursively validates that all the contained objects are property list objects (instances of NSData, NSDate, NSNumber, NSString, NSArray, or NSDictionary) before writing out the file, and returns NO if all the objects are not property list objects, since the resultant file would not be a valid property list.

So whatever you set at dict.SetObject() should be one of the above mentioned types.

loading

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
}
七禾 2024-12-06 10:04:25

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

The recommended way to persist data like this is to use Core Data. While NSUserDefaults can be used to store more or less anything it's only supposed to be used to store preferences.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文