2011-08-14 34 views
48

Tôi sẽ lưu trữ một vài chuỗi (có thể 10-20). Tôi không chắc chắn nếu tôi nên sử dụng NSUserDefaults để lưu chúng, hoặc viết chúng ra một plist. Những gì được coi là thực hành tốt nhất? NSUserDefaults có vẻ như nó là ít dòng mã hơn, do đó nhanh hơn để thực hiện.Tôi có nên sử dụng NSUserDefaults hoặc plist để lưu trữ dữ liệu không?

Tôi muốn thêm rằng các giá trị chuỗi này sẽ được thêm/xóa bởi người dùng.

Trả lời

82

Tôi giả sử một mảng, nhưng nó cũng sẽ hoạt động với từ điển.

Userdefaults, Core Data and Plists đều có thể đọc/ghi nhưng nếu bạn sử dụng plist, bạn cần phải chú ý đến những gì bạn đặt nó. Xem phần plist xuống dưới đây.

Dữ liệu cốt lõi Tôi nghĩ rằng đó là cách quá mức cần thiết, nó chỉ là chuỗi. Đó là nghĩa vụ phải được sử dụng khi bạn muốn tồn tại các đối tượng phức tạp hơn.

NSUserDefaults:

Nó khá nhanh và dễ dàng để làm, mặc dù đó là nghĩa vụ để lưu trữ chỉ thiết lập người dùng. Để ghi chúng vào userdefaults:

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

Để đọc từ userdefaults:

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

Plist:

Nếu dây của bạn sẽ được thay đổi, bạn sẽ cần phải viết và đọc một plist nhưng bạn không thể viết vào tài nguyên của ứng dụng của bạn.

  1. Để có một đọc/ghi plist đầu tiên tìm ra thư mục tài liệu

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *stringsPlistPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Strings.plist"]; 
    
  2. Tạo mảng (Tôi giả định các dây là string1, ...)

    NSArray *stringsArray = [[NSArray alloc] arrayWithObjects: string1, string2, string3, nil]; 
    
  3. Viết nó vào tập tin

    [stringsArray writeToFile:stringsPlistPath atomically:YES]; 
    

Để đọc plist:

  1. Tìm thư mục tài liệu

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *stringsPlistPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Strings.plist"]; 
    
  2. đã đọc nó trong:

    NSArray *stringsArray = [NSArray arrayWithContentsOfFile:stringsPlistPath]; 
    
+1

Tôi đã triển khai giải pháp PList cho danh sách các URL được sử dụng gần đây. Có vẻ như PList là cách tiếp cận chính xác cho vấn đề của tôi. Nhưng tôi phải nói rằng sau khi đã làm tương tự trên Android, điều này đáng ngạc nhiên hơn nhiều liên quan đến xa như một đường cong học tập và nỗ lực tổng thể. Vì vậy, tôi phải bình luận và cảm ơn rất nhiều cho mã ví dụ trên ... – user574771

+2

Câu hỏi ... khi bạn nói "bạn không thể viết vào tài nguyên ứng dụng của mình", bạn có nghĩa là chúng tôi không thể viết thư cho một plist chúng ta tạo ra và cư trú từ bên trong xcode? – crazyCoder

+1

Bạn chỉ có thể viết trong thư mục Tài liệu của ứng dụng. Vì vậy, bạn có thể sao chép plist đó từ thư mục Resources vào thư mục Documents lúc runtime và sau đó chỉnh sửa nó. – doppioslash

1

Cách được khuyến nghị để duy trì dữ liệu như thế này là sử dụng Dữ liệu cốt lõi. Mặc dù NSUserDefaults có thể được sử dụng để lưu trữ nhiều hơn hoặc ít hơn bất cứ thứ gì mà nó chỉ được sử dụng để lưu trữ các sở thích.

+1

Tại sao Core Data là thích hợp hơn để một plist cho một số ít các chuỗi? – jlehr

+0

Vì sau đó khung sẽ xử lý tất cả các chi tiết như xử lý tệp, đồng bộ hóa và xử lý lỗi. –

+0

@MarcusKarlsson NSUserDefault cũng sẽ cung cấp xử lý này cho OP. Số lượng nhỏ các chuỗi các danh sách OP dường như tôi tương đương với sở thích của người dùng hơn, mặc dù nhiều thông tin hơn sẽ hữu ích khi được hướng dẫn tại đây. –

2

Tùy thuộc vào nội dung bạn muốn lưu trữ và lý do. NSUserDefaults có nghĩa là để lưu trữ các sở thích của người dùng. Bạn có thể thử sử dụng nó cho những thứ khác, nhưng bạn có lẽ không nên.

Nếu không, nếu nhu cầu của bạn đơn giản thì tệp plist khá đơn giản. Bạn cũng có thể sử dụng dữ liệu cốt lõi hoặc đưa ra định dạng tệp của riêng mình. Nói chung, tôi sử dụng plist cho các nhiệm vụ đơn giản và sau đó chuyển sang dữ liệu cốt lõi cho bất kỳ điều gì phức tạp hơn.

7

Nếu bạn đang lưu trữ 10-20 chuỗi và đang tìm kiếm không quá nhiều dòng mã, dữ liệu cốt lõi chắc chắn là quá nhiều chi phí. Tôi khuyên bạn nên đi với plist. Không có nhiều mã:

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

NSUserDefaultults sẽ lưu trữ tùy chọn người dùng vào tệp vào thư mục Library/Preferences. Về lý thuyết nó chỉ phục vụ để lưu trữ một số ứng dụng/tài sản người dùng.

Tệp Plist hữu ích để quản lý một tệp. Nếu bạn cần quản lý nhiều hơn, bạn nên sử dụng Coredata. Không có giới hạn về kích thước của tệp plist. Nếu không, bạn phải cẩn thận với tập tin plist bởi vì khi bạn cần lưu hoặc đọc nó toàn bộ nội dung của tập tin sẽ được tải vào bộ nhớ.

2

Sử dụng một plist là một lựa chọn tốt để lưu trữ chuỗi của bạn nếu chuỗi không chỉ thiết lập người dùng có thể đi trong NSUserDefaults. Như đã đề cập, khi sử dụng một plist bạn phải lưu trữ plist của bạn trong thư mục Documents để viết vào nó, bởi vì bạn không thể viết vào tài nguyên của ứng dụng của riêng bạn. Khi tôi lần đầu tiên học được điều này, tôi không rõ nơi thư mục Bundle của ứng dụng của bạn là gì so với thư mục Documents, vì vậy tôi nghĩ rằng tôi sẽ đăng mã ví dụ ở đây mà bản sao đầu tiên được gọi là "Strings.plist" (bạn đã có trong thư mục Bundle của ứng dụng của riêng bạn) vào thư mục Documents, sau đó ghi vào thư mục đó và đọc từ nó.

// 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 cuối cùng lưu trữ tất cả NSUserDefaults dữ liệu vào tệp plist. Vì vậy, nó sẽ không ảnh hưởng đến hiệu suất nếu đó là mối quan tâm của bạn. Cá nhân tôi thích sử dụng NSUserDefaults cho dữ liệu nhỏ và plist cho một tập hợp dữ liệu tương đối lớn.

Lưu ý: Không được lưu trữ bất kỳ thông tin nhạy cảm nào trong NSUserDefaults vì bất kỳ ai cũng có thể xem dữ liệu đó.

1

dùng plist

  1. Tạo một plist sử dụng Xcode

Viết một giá trị cho plist

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

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

Đọc một giá trị từ plist

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

NSUSerDefaults thực sự nhanh chóng triển khai, nhưng chủ yếu là khi ứng dụng của bạn phát triển, bạn muốn lưu trữ nhiều hơn và nhiều hơn nữa, tôi đã truy cập trực tiếp các tệp plist.

Chủ yếu, mọi người muốn lưu trữ danh sách thứ gì đó, vì vậy đây là phần chia sẻ của tôi về cách thực hiện điều này với NSDictionary.Điều này không yêu cầu bạn phải tạo một file plist đầu tiên, nó sẽ được tạo ra ở lần đầu tiên tiết kiệm một cái gì đó

xcode 7 beta, Swift 2,0

tiết kiệm

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

ít lưu ý từ tài liệu:

NSDictionary.writeToFile (path: atomically :)

Phương pháp này một cách đệ quy xác nhận rằng tất cả các đối tượng chứa là những đối tượng danh sách tài sản (trường hợp của NSData, NSDate, NSNumber, NSString, NSArray, hoặc NSDictionary) trước khi viết ra các tập tin, và trả về NO nếu tất cả các đối tượng không phải là bất động sản liệt kê các đối tượng, vì tệp kết quả sẽ không phải là một danh sách thuộc tính hợp lệ.

Vì vậy, bất cứ điều gì bạn đặt ở dict.SetObject() phải là một trong các loại được đề cập ở trên.

tải

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 
} 
Các vấn đề liên quan