2011-08-14 77 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 
} 
相關問題