久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

IOS之數(shù)據(jù)持久化

 螢火與皓月 2015-01-20

9.1 數(shù)據(jù)持久化概述

9.2 iOS應用程序目錄結構

9.3 讀寫屬性列表

9.4 對象歸檔

9.5 訪問SQLite

9.1 數(shù)據(jù)持久化概述

iOS中可以有四種持久化數(shù)據(jù)的方式: 屬性列表,、對象歸檔,、SQLite3和Core Data

9.2 iOS應用程序目錄結構

iOS應用程序運行在Mac os模擬器時候,有一下臨時目錄模擬器3.1.3為例子:

/Users/tony/Library/Application Support/iPhone Simulator/3.1.3/Applications

wps_clip_image-26293

IOS應用程序采用沙盒原理設計,,ios每個應用程序都有自己的3個目錄(Document,Library,tmp),,互相之間不能訪問。

Documents存放應用程序的數(shù)據(jù),。

Library目錄下面還有Preferences和Caches目錄,,Preferences目錄存放應用程序的使用偏好,Caches目錄與Documents很相 似可以存放應用程序的數(shù)據(jù),。

tmp目錄供應用程序存儲臨時文件,。

9.3 讀寫屬性列表

讀取Documents目錄下文件

可以獲得應用程序的Documents文件夾。

    NSArray* myPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* myDocPath = [myPaths objectAtIndex:0];

獲取文件的完整路徑,。

- (NSString*)filePath:(NSString*)fileName {
    NSArray* myPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* myDocPath = [myPaths objectAtIndex:0];
    NSString* filePath = [myDocPath stringByAppendingPathComponent:fileName];
    return filePath;
}

 

獲取tmp目錄

獲取應用程序的tmp目錄要比獲取Documents目錄容易的多,。使用函數(shù)NSTemporaryDirectory ()可以獲得tmp目錄路徑。

NSString* tempPath = NSTemporaryDirectory();

獲取文件的完整路徑,。

NSString* tempFile = [tempPath stringByAppendingPathComponent:@"properties.plist"];

 

屬性列表文件實例 :PropertesList

wps_clip_image-4791

PropertesListViewController.h

復制代碼
#import "Student.h"

@interface ViewController : UIViewController

@property (retain, nonatomic) IBOutlet UITextField *studentNo;
@property (retain, nonatomic) IBOutlet UITextField *studentName;
@property (retain, nonatomic) IBOutlet UITextField *studentClass;
- (IBAction)save:(id)sender;
- (IBAction)load:(id)sender;
- (IBAction)endEditing:(id)sender;
- (IBAction)saveToArchiver:(id)sender;
- (IBAction)loadFromArchiver:(id)sender;
- (NSString*)filePath:(NSString*)fileName;
@end
復制代碼

 

PropertesListViewController.m

復制代碼
@synthesize studentNo;
@synthesize studentName;
@synthesize studentClass;

- (NSString*)filePath:(NSString*)fileName {
    NSArray* myPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* myDocPath = [myPaths objectAtIndex:0];
    NSString* filePath = [myDocPath stringByAppendingPathComponent:fileName];
    return filePath;
}

- (IBAction)save:(id)sender {

    NSString* fileName = [self filePath:@"properties.plist"];
    NSLog(fileName);
    NSMutableArray* data = [[NSMutableArray alloc]init];

    [data addObject:studentNo.text];
    [data addObject:studentName.text];
    [data addObject:studentClass.text];
    [data writeToFile:fileName atomically:YES];
}

- (IBAction)load:(id)sender {
    NSString* fileName = [self filePath:@"properties.plist"];
    if ([[NSFileManager defaultManager]fileExistsAtPath:fileName]) {
        NSArray* data = [[NSArray alloc]initWithContentsOfFile:fileName];
        studentNo.text = [data objectAtIndex:0];
        studentName.text = [data objectAtIndex:1];
        studentClass.text = [data objectAtIndex:2];
        [data release];
    }
    
}

- (IBAction)endEditing:(id)sender {
    [sender resignFirstResponder];
}
復制代碼

wps_clip_image-8352

wps_clip_image-11973

9.4 對象歸檔

對象歸檔實例:Encoding

對象歸檔

“歸檔”是值另一種形式的序列化,,對模型對象進行歸檔的技術可以輕松將復雜的對象寫入文件,然后再從中讀取它們,,只要在類中實現(xiàn)的每個屬性都是基本數(shù)據(jù)類型(如int或float)或都是符合NSCoding協(xié)議的某個類的實例,,你就可以對你的對象進行完整歸檔。

實現(xiàn)NSCoding協(xié)議

NSCoding協(xié)議聲明了兩個方法: -(void)encodeWithCoder:(NSCoder *)aCoder,,是將對象寫入到文件中,。 

-(id)initWithCoder:(NSCoder *)aDecoder,是將文件中數(shù)據(jù)讀入到對象中,。

實現(xiàn)NSCopying協(xié)議

NSCopying協(xié)議聲明了一個方法: -(id)copyWithZone:(NSZone *)zone ,,是將對象復制方法。 

Student.h

復制代碼
@interface Student : NSObject<NSCoding, NSCopying>

@property (retain, nonatomic) NSString* studentNo;
@property (retain, nonatomic) NSString* studentName;
@property (retain, nonatomic) NSString* studentClass;

@end
復制代碼

 

Student.m

復制代碼
#import "Student.h"

@implementation Student

@synthesize studentNo = _studentNo;
@synthesize studentName = _studentName;
@synthesize studentClass = _studentClass;

#pragma mark NSCopying

- (id)copyWithZone:(NSZone *)zone {
    Student* copy = [[[self class]allocWithZone:zone]init];
    copy.studentNo = [_studentNo copyWithZone:zone];
    copy.studentName = [_studentName copyWithZone:zone];
    copy.studentClass = [_studentClass copyWithZone:zone];
    return copy;
}

#pragma mark  NSCoding

- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:_studentNo forKey:@"studentNo"];
    [aCoder encodeObject:_studentName forKey:@"studentName"];
    [aCoder encodeObject:_studentClass forKey:@"studentClass"];
}
- (id)initWithCoder:(NSCoder *)aDecoder {
    _studentNo = [aDecoder decodeObjectForKey:@"studentNo"];
    _studentName = [aDecoder decodeObjectForKey:@"studentName"];
    _studentClass = [aDecoder decodeObjectForKey:@"studentClass"];
    return self;
}
-(NSString*)description {
    return [[[NSString alloc]initWithFormat:@"no:%@ name:%@ class:%@", _studentNo, _studentName, _studentClass]autorelease];
}

- (void)dealloc {
    [_studentName release];
    [_studentClass release];
    [_studentNo release];
    [super dealloc];
}
@end
復制代碼

 

EncodingViewController.h

詳細見上,。

EncodingViewController.m

復制代碼
- (IBAction)saveToArchiver:(id)sender {
    NSString* fileName = [self filePath:@"student.archiver"];
    NSMutableData* data = [NSMutableData data];
    NSKeyedArchiver* archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
    Student* student = [[Student alloc]init];
    student.studentNo = studentNo.text;
    student.studentName = studentName.text;
    student.studentClass = studentClass.text;
    [archiver encodeObject:student forKey:@"myStudent"];
    [archiver finishEncoding];
    [data writeToFile:fileName atomically:YES];
    [archiver release];
    [student release];
}
復制代碼

NSMutableData * theData = [NSMutableData data];用于包含編碼的數(shù)據(jù),。

NSKeyedArchiver * archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:theData];創(chuàng)建NSKeyedArchiver實例,用于將對象歸檔到此theData實例中,。

[archiver encodeObject:student forKey:@"mystudent"]; 使用“鍵-值”對編碼來對希望包含在歸檔中的對象進行歸檔,。

[theData writeToFile:filename atomically:YES]; 寫入數(shù)據(jù)到歸檔文件。

EncodingViewController.m

復制代碼
- (IBAction)loadFromArchiver:(id)sender {
    NSString* fileName = [self filePath:@"student.archiver"];
    NSData* data = [NSData dataWithContentsOfFile:fileName];
    if ([data length] > 0) {
        NSKeyedUnarchiver* unArchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data];
        Student* student = [unArchiver decodeObjectForKey:@"myStudent"];
        studentNo.text = student.studentNo;
        studentName.text = student.studentName;
        studentClass.text = student.studentClass;
        [unArchiver finishDecoding];
        [unArchiver release];
    }
}
復制代碼

 

NSData * theData =[NSData dataWithContentsOfFile:filename];從歸檔文件中獲得NSData實例,。

NSKeyedUnarchiver * archiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:theData]; 

創(chuàng)建一個NSKeyedUnarchiver實例對數(shù)據(jù)進行解碼,。Student *student = [archiver decodeObjectForKey:@"mystudent"];

使用與歸檔編碼使用相同的鍵對象進行解碼。

9.5 訪問SQLite

SQLite數(shù)據(jù)庫

SQLite是一個開源的嵌入式關系數(shù)據(jù)庫,,它在2000年由D. Richard Hipp發(fā)布,,它的減少應用程序管理數(shù)據(jù)的開銷,SQLite可移植性好,,很容易使用,,很小,,高效而且可靠。

SQLite嵌入到使用它的應用程序中,,它們共用相同的進程空間,,而不是單獨的一個進程。從外部看,,它并不像一個RDBMS,,但在進程內部,它卻是完整的,,自包含的數(shù)據(jù)庫引擎,。 嵌入式數(shù)據(jù)庫的一大好處就是在你的程序內部不需要網(wǎng)絡配置,也不需要管理,。因為客戶端和服務器在同一進程空間運行,。SQLite 的數(shù)據(jù)庫權限只依賴于文件系統(tǒng),,沒有用戶帳戶的概念,。SQLite 有數(shù)據(jù)庫級鎖定,沒有網(wǎng)絡服務器,。它需要的內存,,其它開銷很小,適合用于嵌入式設備,。你需要做的僅僅是把它正確的編譯到你的程序,。

SQLite數(shù)據(jù)類型

SQLite是無類型的,這意味著你可以保存任何類型的數(shù)據(jù)到你所想要保存的任何表的任何列中, 無

論這列聲明的數(shù)據(jù)類型是什么,,對于SQLite來說對字段不指定類型是完全有效的,,如: 

Create Table ex1(a, b, c); 

SQLite允許忽略數(shù)據(jù)類型,但是仍然建議在你的Create Table語句中指定數(shù)據(jù)類型,, 因為數(shù)據(jù)類型對于你和其他的程序員交流,, 或者你準備換掉你的數(shù)據(jù)庫引擎。 SQLite支持常見的數(shù)據(jù)類型,, 如:

wps_clip_image-15813

在iOS中使用SQLite3

為了能夠在iOS中使用SQLite3需要是將libsqlite3.dylib類庫添加到Xcode工程中,,在工程的Frameworks(框架) 文件夾右鍵添加存在Frameworks

wps_clip_image-1001

或者導航到 /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/ iPhoneSimulator<version>.sdk/usr/lib 目錄下面找到libsqlite3.dylib.

實例:StudentSQLite3

wps_clip_image-24545

StudentSQLite3ViewController.h

復制代碼
#import "sqlite3.h"

#define DATA_FILE @"data.sqlite3"
#define TABLE_NAME @"student"
#define FIELDS_NAME_SID @"studentId"
#define FIELDS_NAME_SNAME @"studentName"
#define FIELDS_NAME_SCLASS @"studentClass"

@interface ViewController : UIViewController {
    sqlite3* db;
}
@property (retain, nonatomic) IBOutlet UITextField *studentId;
@property (retain, nonatomic) IBOutlet UITextField *studentName;
@property (retain, nonatomic) IBOutlet UITextField *studentClass;
- (IBAction)saveFromSqlite:(id)sender;
- (IBAction)loadFromSqlite:(id)sender;


-(NSString*)dataFile;
-(IBAction)textFieldDoneEditing:(id)sender;

@end
復制代碼

 

StudentSQLite3ViewController.m

復制代碼
@synthesize studentId;
@synthesize studentName;
@synthesize studentClass;

-(NSString*)dataFile {
    NSArray* myPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* myDocPath = [myPaths objectAtIndex:0];
    NSString* fileName = [myDocPath stringByAppendingFormat:DATA_FILE];
    return fileName;
}
復制代碼

 

無參數(shù)SQLite3處理過程

1、打開數(shù)據(jù)庫sqlite3_open,。

2,、創(chuàng)建數(shù)據(jù)庫表和執(zhí)行SQL語句sqlite3_exec。

3,、釋放資源sqlite3_close,。

創(chuàng)建數(shù)據(jù)庫

復制代碼
- (void)viewDidLoad {
    [super viewDidLoad];
    NSString* fileName = [self dataFile];
    NSLog(@"%@", fileName);
    if (sqlite3_open([fileName UTF8String], &db) != SQLITE_OK) {
        sqlite3_close(db);
        NSAssert(NO, @"OPEN SQLITE DATABASE ERROR!");
    } else {
        char* error;
        NSString* createSQL = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@(%@ TEXT PRIMARY KEY, %@ TEXT, %@% TEXT);", 
                                  TABLE_NAME, FIELDS_NAME_SID, FIELDS_NAME_SNAME, FIELDS_NAME_SCLASS];
if (sqlite3_exec(db, [createSQL UTF8String], NULL, NULL, &error)) { sqlite3_close(db); NSAssert1(NO, @"CREATE TABLE ERROR", error); } else { sqlite3_close(db); } } }
復制代碼

 

sqlite3_open([[self dataFilePath] UTF8String], &db) != SQLITE_OK sqlite3_open打開數(shù)據(jù)庫,,注意:在sqlite3中的函數(shù)都是使用C字符串[self dataFilePath] UTF8String]是將NSString字符串轉換為C字符串,,&db是sqlite3指針(* db)的地址,。

該函數(shù)sqlite3_open返回SQLITE_OK打開成功。

sqlite3_exec(db, [tablesql UTF8String], NULL, NULL, &err) != SQLITE_OK

sqlite3_exec是執(zhí)行任何不帶返回值sql語句,,第2個參數(shù)是要執(zhí)行的sql語句,,第3個參數(shù)是要回調函數(shù),第4個參數(shù)是要回調函數(shù)的參數(shù),,第5個參數(shù)是執(zhí)行出錯的字符串,。

sqlite3_close(db); 是關閉數(shù)據(jù)庫。

NSAssert是斷言函數(shù),,當斷言失敗時候打印信息,。

NSAssert1是帶有一個參數(shù)的NSAssert函數(shù),此外還有NSAssert2等函數(shù),。

有參數(shù)的SQLite3處理過程

1,、打開數(shù)據(jù)庫sqlite3_open。

2,、預處理SQL語句sqlite3_prepare_v2,。

3、綁定參數(shù)sqlite3_bind_text,。

4,、執(zhí)行語句sqlite3_step(statement) 。

5,、釋放資源sqlite3_finalize?sqlite3_close,。

數(shù)據(jù)保存

復制代碼
- (IBAction)saveFromSqlite:(id)sender {
    NSString* fileName = [self dataFile];
    NSLog(@"%@", fileName);
    if (sqlite3_open([fileName UTF8String], &db)) {
        sqlite3_close(db);
        NSAssert(NO, @"OPEN DATABASE ERROR");
    } else {
        NSString* sqlStr = [NSString stringWithFormat:@"INSERT OR REPLACE INTO %@(%@, %@, %@) VALUES(?, ?, ?)",TABLE_NAME, FIELDS_NAME_SID, FIELDS_NAME_SNAME, FIELDS_NAME_SCLASS];
        sqlite3_stmt* statement;
        //預處理過程
        if (sqlite3_prepare(db, [sqlStr UTF8String], -1, &statement, NULL) == SQLITE_OK) {
            //綁定參數(shù)開始
            sqlite3_bind_text(statement, 1, [studentId.text UTF8String], -1, NULL);
            sqlite3_bind_text(statement, 2, [studentName.text UTF8String], -1, NULL);
            sqlite3_bind_text(statement, 3, [studentClass.text UTF8String], -1, NULL);
            //執(zhí)行插入
            if (sqlite3_step(statement) != SQLITE_DONE) {
                NSAssert(0, @"INSERT DATABASE ERROR!");
            }
        }
        sqlite3_finalize(statement);
        sqlite3_close(db);
    }
}
復制代碼

 

sqlite3_prepare_v2(db, [sqlStr UTF8String], -1, &statement, nil) == SQLITE_OK

sqlite3_prepare_v2執(zhí)行sql語句,第3個參數(shù)-1代表全部sql字符串長度,,第4個參數(shù)&statement是sqlite3_stmt指針(* statement)的地址,,第5個參數(shù)是sql語句沒有被執(zhí)行的部分語句。

sqlite3_bind_text(statement, 1, [studentId.text UTF8String], -1, NULL);

是綁定參數(shù),,第2個參數(shù)為序號(從1開始),,第3個參數(shù)為字符串值,第4個參數(shù)為字符串長度,。 第5個參數(shù)為一個函數(shù)指針,,SQLITE3執(zhí)行完操作后回調此函數(shù),通常用于釋放字符串占用的內存,。

sqlite3_step(statement) != SQLITE_DONE判斷是否執(zhí)行完成sql語句執(zhí)行,。

sqlite3_finalize(statement)和sqlite3_close(db)釋放資源。

查詢數(shù)據(jù)

復制代碼
- (IBAction)loadFromSqlite:(id)sender {
    NSString* fileName = [self dataFile];
    NSLog(@"%@", fileName);
    if (sqlite3_open([fileName UTF8String], &db) != SQLITE_OK) {
        sqlite3_close(db);
        NSAssert(NO, @"OPEN DATABASE ERROR!");
    } else {
        NSString* sqlStr = [NSString stringWithFormat:@"SELECT %@,%@,%@ FROM %@ WHERE %@=?", 
                            FIELDS_NAME_SID, FIELDS_NAME_SNAME, FIELDS_NAME_SCLASS, TABLE_NAME, FIELDS_NAME_SID];
        sqlite3_stmt* statement;
        //預處理過程
        if (sqlite3_prepare_v2(db, [sqlStr UTF8String], -1, &statement, NULL) == SQLITE_OK) {
            //綁定參數(shù)開始
            sqlite3_bind_text(statement, 1, "1000", -1, NULL);
            //執(zhí)行
            while (sqlite3_step(statement) == SQLITE_ROW) {
                char* field1 = (char*)sqlite3_column_text(statement, 0);
                NSString* field1Str = [[NSString alloc]initWithUTF8String:field1];
                studentId.text = field1Str;
                
                char* field2 = (char*)sqlite3_column_text(statement, 1);
                NSString* field2Str = [[NSString alloc]initWithUTF8String:field2];
                studentName.text = field2Str;
                
                char* field3 = (char*)sqlite3_column_text(statement, 2);
                NSString* field3Str = [[NSString alloc]initWithUTF8String:field3];
                studentClass.text = field3Str;
                
                [field1Str release];
                [field2Str release];
                [field3Str release];
            }
        }
        sqlite3_finalize(statement);
        sqlite3_close(db);
    }
}
復制代碼

 

while (sqlite3_step(statement) == SQLITE_ROW) sqlite3_step(statement) == SQLITE_ROW單步執(zhí)行并判斷sql語句執(zhí)行的狀態(tài),。

char *field1 = (char *) sqlite3_column_text(statement, 0); sqlite3_column_text(statement, 0);取出字段值,,第2個參數(shù)是列的順序,序號是從0開始,。

NSString *field1Str = [[NSString alloc] initWithUTF8String: field1];構建NSSting字符串,。

其它部分代碼

復制代碼
-(IBAction)textFieldDoneEditing:(id)sender {
    [sender resignFirstResponder];
}
- (void)viewDidUnload
{
    [self setStudentId:nil];
    [self setStudentName:nil];
    [self setStudentClass:nil];
    [super viewDidUnload];
}

- (void)dealloc {
    [studentId release];
    [studentName release];
    [studentClass release];
    [super dealloc];
}
復制代碼

 

注:
1 本教程是基于關東升老師的教程
2 基于黑蘋果10.6.8和xcode4.2
3 本人初學,,有什么不對的望指教
4 教程會隨著本人學習,持續(xù)更新
5 教程是本人從word筆記中拷貝出來了,,所以格式請見諒

    本站是提供個人知識管理的網(wǎng)絡存儲空間,,所有內容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內容中的聯(lián)系方式,、誘導購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權內容,,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多