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

时间:2011-08-14 18:37:07

标签: iphone objective-c cocoa-touch plist nsuserdefaults

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

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

9 个答案:

答案 0 :(得分:84)

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

Userdefaults,Core Data和Plists都可以读/写,但是如果你使用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 atomically:YES];
    
  4. 阅读plist:

    1. 找到文档目录

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

      NSArray *stringsArray = [NSArray arrayWithContentsOfFile:stringsPlistPath];
      

答案 1 :(得分:8)

如果要存储10-20个字符串并且正在寻找不太多的代码行,那么核心数据肯定是过多的开销。我建议和plist一起去。不是很多代码:

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

答案 2 :(得分:8)

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

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

答案 3 :(得分:5)

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

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

答案 4 :(得分:2)

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

否则,如果您的需求很简单,那么plist文件非常简单。您还可以使用核心数据或提供自己的文件格式。一般来说,我使用plist进行简单的任务,然后转移到核心数据以获得更复杂的任何内容。

答案 5 :(得分:2)

如果字符串不仅仅是可以进入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];

答案 6 :(得分:2)

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(路径:原子:)

     

此方法以递归方式验证所有包含的对象是属性列表对象(NSDataNSDateNSNumberNSStringNSArray的实例,或者NSDictionary)在写出文件之前,如果所有对象都不是属性列表对象,则返回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
}

答案 7 :(得分:1)

保持这样的数据的推荐方法是使用Core Data。虽然NSUserDefaults可用于存储更多或更少的东西,但它只能用于存储首选项。

答案 8 :(得分:1)

使用.plist

  1. 使用Xcode创建一个plist
  2. 为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"];