2011-08-14 103 views
48

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

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

回答

82

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

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. 创建阵列(我假设的字符串是字符串1,...)

    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]; 
    
+1

我为最近使用的URL列表实施了PList解决方案。看来,PList是我的问题的正确方法。但我不得不说,在Android上完成相同的工作后,就学习曲线和整体工作而言,这非常令人惊讶地涉及更多。所以我必须对上面的示例代码发表评论和表示感谢...... – user574771

+2

问题......当你说“你不能写入你的应用程序资源”时,你的意思是我们不能写信给plist我们创建并从xcode内部填充? – crazyCoder

+1

您只能在应用程序的Documents目录中编写代码。因此,您可以在运行时将资源目录中的plist复制到Documents目录,然后对其进行编辑。 – doppioslash

1

保持此类数据的推荐方式是使用核心数据。虽然NSUserDefaults可以用来存储更多或更少的东西,但它只能用于存储首选项。

+1

为什么会核心数据是最好的字符串寥寥的plist? – jlehr

+0

因为那么框架将处理所有的细节,如文件处理,同步和错误处理。 –

+0

@MarcusKarlsson NSUserDefaults也将为OP提供这种处理。 OP列出的少量字符串在我看来似乎更符合用户偏好,但更多信息将有助于在此处指导。 –

2

这取决于你想要存储什么以及为什么。 NSUserDefaults用于存储用户首选项。你可以尝试用它来做其他事情,但你可能不应该这样做。

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

7

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

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

将NSUserDefaults的用户喜好存储到一个文件到库/首选项文件夹中。理论上它只用于存储一些应用程序/用户属性。

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

2

使用的plist是一个不错的选择如果字符串存储你的字符串而不仅仅是可以进入NSUserDefaults的用户设置。如前所述,使用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]; 
7

iOS最终将所有NSUserDefaults数据存储到plist文件中。所以如果这是你的担心,它不会影响性能。我个人比较喜欢使用NSUserDefaults来处理小数据,而使用plist来处理相对较大的一组数据。

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

1

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

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

大多数人想要存储一些东西,所以这里是我的共享如何使用NSDictionary做到这一点。这并不要求你先创建一个plist文件,它会在第一时间保存的东西

的Xcode 7测试版中创建,雨燕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 :)

这种方法递归地验证了所有包含的对象是写出来的文件之前,属性列表对象(的NSData情况下,NSDateNSNumberNSStringNSArray,或者NSDictionary),并且不返回,如果所有的对象都没有属性列表对象,因为生成的文件不会是有效的属性列表。

所以无论你在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 
} 
相关问题