1、沙盒機制sql
沙盒就是一個文件,沙盒的目錄結構:數據庫
"應用程序包" Documents Library Caches Preferences tmp
文件夾解釋:安全
"應用程序包": 這裏面存放的是應用程序的源文件,包括資源文件和可執行文件。多線程
NSString *path = [[NSBundle mainBundle] bundlePath]; NSLog(@"%@", path);
Documents: 最經常使用的目錄,iTunes同步該應用時會同步此文件夾中的內容,適合存儲重要數據。atom
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; NSLog(@"%@", path);
Library/Caches: iTunes不會同步此文件夾,適合存儲體積大,不須要備份的非重要數據。線程
NSString *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject; NSLog(@"%@", path);
Library/Preferences: iTunes同步該應用時會同步此文件夾中的內容,一般保存應用的設置信息。code
tmp: iTunes不會同步此文件夾,系統可能在應用沒運行時就刪除該目錄下的文件,因此此目錄適合保存應用中的一些臨時文件,用完就刪除。orm
NSString *path = NSTemporaryDirectory(); NSLog(@"%@", path);
2、plist文件(屬性列表)sqlite
plist文件是將某些特定的類,經過XML文件的方式保存在目錄中。對象
NSArray; NSMutableArray; NSDictionary; NSMutableDictionary; NSData; NSMutableData; NSString; NSMutableString; NSNumber; NSDate;
得到文件
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; NSString *fileName = [path stringByAppendingPathComponent:@"123.plist"];
存儲數據
NSArray *array = @[@"123", @"456", @"789"]; [array writeToFile:fileName atomically:YES];
讀取數據
NSArray *result = [NSArray arrayWithContentsOfFile:fileName]; NSLog(@"%@", result);
說明:存儲時使用writeToFile: atomically:方法,讀取時使用arrayWithContentsOfFile:方法。
3、preference(偏好設置)
使用方法
//1.得到NSUserDefaults文件 NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; //2.向文件中寫入內容 [userDefaults setObject:@"AAA" forKey:@"a"]; [userDefaults setBool:YES forKey:@"sex"]; [userDefaults setInteger:21 forKey:@"age"]; //2.1當即同步 [userDefaults synchronize]; //3.讀取文件 NSString *name = [userDefaults objectForKey:@"a"]; BOOL sex = [userDefaults boolForKey:@"sex"]; NSInteger age = [userDefaults integerForKey:@"age"]; NSLog(@"%@, %d, %ld", name, sex, age);
使用說明
偏好設置是專門用來保存應用程序的配置信息。
偏好設置會將全部數據保存到同一個文件中。即preference目錄下的一個以此應用包名來命名的plist文件。
4、NSKeyedArchiver(歸檔)
準備工做
遵循協議,設置屬性
//1.遵循NSCoding協議 @interface Person : NSObject<NSCoding> //2.設置屬性 @property (strong, nonatomic) UIImage *avatar; @property (copy, nonatomic) NSString *name; @property (assign, nonatomic) NSInteger age; @end
2.實現協議方法
//解檔 - (id)initWithCoder:(NSCoder *)aDecoder { if ([super init]) { self.avatar = [aDecoder decodeObjectForKey:@"avatar"]; self.name = [aDecoder decodeObjectForKey:@"name"]; self.age = [aDecoder decodeIntegerForKey:@"age"]; } return self; } //歸檔 - (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:self.avatar forKey:@"avatar"]; [aCoder encodeObject:self.name forKey:@"name"]; [aCoder encodeInteger:self.age forKey:@"age"]; }
3.具體使用
1. 須要把對象歸檔是調用NSKeyedArchiver的工廠方法 archiveRootObject: toFile: 方法。
NSString *file = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"person.data"]; Person *person = [[Person alloc] init]; person.avatar = self.avatarView.image; person.name = self.nameField.text; person.age = [self.ageField.text integerValue]; [NSKeyedArchiver archiveRootObject:person toFile:file];
2.須要從文件中解檔對象就調用NSKeyedUnarchiver的一個工廠方法 unarchiveObjectWithFile: 便可。
NSString *file = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"person.data"]; Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:file]; if (person) { self.avatarView.image = person.avatar; self.nameField.text = person.name; self.ageField.text = [NSString stringWithFormat:@"%ld", person.age]; }
說明:
若是須要歸檔的類是某個自定義類的子類時,就須要在歸檔和解檔以前先實現父類的歸檔和解檔方法。即 [super encodeWithCoder:aCoder] 和 [super initWithCoder:aDecoder] 方法;
歸檔在iOS中是另外一種形式的序列化,只要遵循了NSCoding協議的對象均可以經過它實現序列化。因爲決大多數支持存儲數據的Foundation和Cocoa Touch類都遵循了NSCoding協議,
5、SQLite(FMDB)
FMDB有三個主要的類:FMDatabase、FMResultSet、FMDatabaseQueue
FMDatabase:一個FMDatabase對象就表明一個單獨的SQLite數據庫,用來執行SQL語句
FMResultSet:使用FMDatabase執行查詢後的結果集
FMDatabaseQueue:用於在多線程中執行多個查詢或更新,它是線程安全的
使用方法
打開數據庫 須要導入sqlite3.dylib
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"person.db"]; FMDatabase *database = [FMDatabase databaseWithPath:path]; if (![database open]) { NSLog(@"數據庫打開失敗!"); }
值得注意的是,Path的值能夠傳入如下三種狀況:
具體文件路徑,若是不存在會自動建立
空字符串@"",會在臨時目錄建立一個空的數據庫,當FMDatabase鏈接關閉時,數據庫文件也被刪除
nil,會建立一個內存中臨時數據庫,當FMDatabase鏈接關閉時,數據庫會被銷燬
更新數據庫
//經常使用方法有如下3種: - (BOOL)executeUpdate:(NSString*)sql, ... - (BOOL)executeUpdateWithFormat:(NSString*)format, ... - (BOOL)executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray *)arguments //示例 [database executeUpdate:@"CREATE TABLE IF NOT EXISTS t_person(id integer primary key autoincrement, name text, age integer)"]; //或者 [database executeUpdate:@"INSERT INTO t_person(name, age) VALUES(?, ?)", @"Bourne", [NSNumber numberWithInt:42]];
說明:在FMDB中,除查詢之外的全部操做,都稱爲「更新」, 如:create、drop、insert、update、delete等操做,使用executeUpdate:方法執行更新。
查詢數據庫
- (FMResultSet *)executeQuery:(NSString*)sql, ... - (FMResultSet *)executeQueryWithFormat:(NSString*)format, ... - (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray *)arguments
應用實例
//1.執行查詢 FMResultSet *result = [database executeQuery:@"SELECT * FROM t_person"]; //2.遍歷結果集 while ([result next]) { NSString *name = [result stringForColumn:@"name"]; int age = [result intForColumn:@"age"]; }
線程安全
建立隊列
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
使用隊列
[queue inDatabase:^(FMDatabase *database) { [database executeUpdate:@"INSERT INTO t_person(name, age) VALUES (?, ?)", @"Bourne_1", [NSNumber numberWithInt:1]]; [database executeUpdate:@"INSERT INTO t_person(name, age) VALUES (?, ?)", @"Bourne_2", [NSNumber numberWithInt:2]]; [database executeUpdate:@"INSERT INTO t_person(name, age) VALUES (?, ?)", @"Bourne_3", [NSNumber numberWithInt:3]]; FMResultSet *result = [database executeQuery:@"select * from t_person"]; while([result next]) { } }];
包裝事務到隊列中
[queue inTransaction:^(FMDatabase *database, BOOL *rollback) { [database executeUpdate:@"INSERT INTO t_person(name, age) VALUES (?, ?)", @"Bourne_1", [NSNumber numberWithInt:1]]; [database executeUpdate:@"INSERT INTO t_person(name, age) VALUES (?, ?)", @"Bourne_2", [NSNumber numberWithInt:2]]; [database executeUpdate:@"INSERT INTO t_person(name, age) VALUES (?, ?)", @"Bourne_3", [NSNumber numberWithInt:3]]; FMResultSet *result = [database executeQuery:@"select * from t_person"]; while([result next]) { } //回滾 *rollback = YES; }];
說明:在多個線程中同時使用一個FMDatabase實例是不明智的。不要讓多個線程分享同一個FMDatabase實例,它沒法在多個線程中同時使用。 若是在多個線程中同時使用一個FMDatabase實例,會形成數據混亂等問題。因此,使用FMDatabaseQueue,它是線程安全的
6、CoreData
地址:CoreData的使用