將陣列資料儲存到檔案中。
儲存陣列資料
在 Objective-C 中,將陣列資料儲存到本地端的檔案非常容易,如下:NSArray *demo = @[@"ABC", @123];
[demo writeToFile:[self filePathOfDocument:@"demo.plist"] atomically:YES];
如此就會在 App 的 Documents 目錄,建立 demo.plist ,內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<string>ABC</string>
<integer>123</integer>
</array>
</plist>
要從檔案載入也很簡單,如下:
NSArray *demo = [NSArray arrayWithContentsOfFile:[self filePathOfDocument:@"demo.plist"]];
但是,這個方法只能儲存 Objective-C 內建的物件,例如 NSString、NSInteger 等,如果是自訂的物件就無法使用。
將自定物件陣列儲存到檔案
要儲存自訂的物件陣列,必須用 NSKeyedArchiver 來封裝,並使用 NSKeyedUnarchiver 來解開。要讓這兩個類類發生作用,必須在自訂物件的類別中加入如何封裝的程式碼。假設我們有一個使用者類別 User.h 有兩個屬性:
#import <Foundation/Foundation.h>
@interface User : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end
在 User.m 中加入封裝用方法:
#import "User.h"
NSString *const KADUserName = @"name";
NSString *const KADUserAge = @"age";
@implementation User
- (id)initWithCoder:(NSCoder *)coder {
self = [super init];
if (self) {
_name = [coder decodeObjectForKey:KADUserName];
_age = [coder decodeIntegerForKey:KADUserAge];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder {
if ([coder isKindOfClass:[NSKeyedArchiver class]]) {
[coder encodeObject:_name forKey:KADUserName];
[coder encodeInteger:_age forKey:KADUserAge];
} else {
[NSException raise:NSInvalidArchiveOperationException
format:@"Only supports NSKeyedArchiver coders"];
}
}
@end
initWithCoder 用來解封裝,encodeWithCoder: 則是用來封裝。這樣 User 類別所建立的物件就能被儲存成檔案。
使用範例如下:
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"建立使用者");
User *user1 = [User new];
user1.name = @"Tony";
user1.age = 18;
User *user2 = [User new];
user2.name = @"Ava";
user2.age = 22;
User *user3 = [User new];
user3.name = @"Karen";
user3.age = 26;
NSArray *users = @[user1, user2, user3];
NSLog(@"儲存使用者");
[self saveUserToFile:users];
NSLog(@"載入使用者");
NSArray *loadUsers = [self loadUserFromFile];
NSLog(@"顯示使用者");
for (User *user in loadUsers) {
NSLog(@"User Name: %@, age:%i", user.name, user.age);
}
}
- (void)saveUserToFile:(NSArray *)users
{
NSString *filePath = [self filePathOfDocument:KADUserPlist];
[NSKeyedArchiver archiveRootObject:users toFile:filePath];
}
- (NSArray *)loadUserFromFile
{
NSString *filePath = [self filePathOfDocument:KADUserPlist];
return [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
}
/**
取得文件目錄路徑(Documents)
*/
- (NSString *)filePathOfDocument:(NSString *)filename
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
return [docDir stringByAppendingPathComponent:filename];
}
另外,在檔案前面還建立了一個檔名常數,
NSString *const KADUserPlist = @"user.plist";
執行結果就如文章一開頭的圖片所示。使用 Finder 開啟 App 的 Documents 目錄,就會發現被建立了一個 user.plist 檔。
我要留言
留言小提醒:
1.回覆時間通常在晚上,如果太忙可能要等幾天。
2.請先瀏覽一下其他人的留言,也許有人問過同樣的問題。
3.程式碼請先將它編碼後再貼上。(線上編碼:http://bit.ly/1DL6yog)
4.文字請加上標點符號及斷行,難以閱讀者恕難回覆。
5.感謝您的留言,您的問題也可能幫助到其他有相同問題的人。