Iphone开发基础教程 (11章 基本数据持久性)--读书笔记

获取Documents目录

NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [path objectAtIndex:0];
    
NSString *filename = [documentsDirectory stringByAppendingFormat:@"thefFile.txt"];

获取tmp目录

NSString *tempPath = NSTemporaryDirectory();
NSString *tempFile = [tempFile stringByAppendingFormat:@"tempFile.txt"];

属性列表序列化

    许多应用程序都使用了属性列表,比如使用属性列表来指定程序首选项,只要字典或数组仅包含特定可序列化的对象,就可以将NSDictionary和NSarray实例写入属性列表及从属性列表创建他们。序列化对象已被转换为字节流,以便存储到文件中,或通过网络进行传输。尽管可以让任何对象可序列化,但是只能将某些对象放置到某个集合类(如NSDictionary或NSArray)中,然后使用该集合的writeToFile方法将他们存储到属性列表

    如果你打算使用属性列表持久保存程序数据,则可以使用NSArray或NDDirectionary容纳需要持久化的数据,假设你放到NSArray或NSDirectionary的所有对象都是可序列化的对象,则可以通过字典或数组实例调用writeToFile:atnomically:方法来编写属性列表

[myArray writeToFile:@"/some/file/location/output.plist" atomically:YES];

1、新建single view application

2、打开viewController.xib,添加控件如图


2、修改控制器

#import 
#define kFilename @"data.plist"

@interface ViewController : UIViewController
{
    IBOutlet UITextField *field1;
    IBOutlet UITextField *field2;
    IBOutlet UITextField *field3;
    IBOutlet UITextField *field4;
}

@property (nonatomic,retain) UITextField *field1;
@property (nonatomic,retain) UITextField *field2;
@property (nonatomic,retain) UITextField *field3;
@property (nonatomic,retain) UITextField *field4;

- (NSString *) dataFilePath;
- (void) applicationWillTerminate:(NSNotification *) notification;

@end

@implementation ViewController
@synthesize field1;
@synthesize field2;
@synthesize field3;
@synthesize field4;

- (NSString *)dataFilePath
{
    NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [path objectAtIndex:0];
    return [documentsDirectory stringByAppendingFormat:@"thefFile.txt"];
}

-(void) applicationWillTerminate:(NSNotification *) notifaction
{
    NSMutableArray *array = [[NSMutableArray alloc ] init];
    [array addObject:field1.text];
    [array addObject:field2.text];
    [array addObject:field3.text];
    [array addObject:field4.text];
    [array writeToFile:[self dataFilePath] atomically:YES];
    [array release];
}

- (void) viewDidLoad
{
    NSString *filePath = [self dataFilePath];
    if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
        NSArray *array = [[NSArray alloc] initWithContentsOfFile:filePath];
        field1.text = [array objectAtIndex:0];
        field2.text = [array objectAtIndex:1];
        field3.text = [array objectAtIndex:2];
        field4.text = [array objectAtIndex:3];
        [array release];
    }
    
    UIApplication *app = [UIApplication sharedApplication];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillTerminate:) name:UIApplicationWillTerminateNotification object:app];
    [super viewDidLoad];
}

- (void)dealloc {
    [field1 release];
    [field2 release];
    [field3 release];
    [field4 release];
    [super dealloc];
}
@end

3、重新打开.xib 按下Control的同时,将File's Owner图标拖放到第一个文本字段,选择field1,第二个连接到field2 ......

对象归档

#define kField1Key @"Field1"
#define kField2Key @"Field2"
#define kField3Key @"Field3"
#define kField4Key @"Field4"

#import 


@interface FourLines : NSObject 
{
    NSString *field1;
    NSString *field2;
    NSString *field3;
    NSString *field4;
}

@property (nonatomic,retain) NSString *field1;
@property (nonatomic,retain) NSString *field2;
@property (nonatomic,retain) NSString *field3;
@property (nonatomic,retain) NSString *field4;

@implementation FourLines
@synthesize field1;
@synthesize field2;
@synthesize field3;
@synthesize field4;

- (void) encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:field1 forKey:kField1Key];
    [aCoder encodeObject:field2 forKey:kField2Key];
    [aCoder encodeObject:field3 forKey:kField3Key];
    [aCoder encodeObject:field4 forKey:kField4Key];
}

- (id) initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super init]) {
        self.field1 = [aDecoder decodeObjectForKey:kField1Key];
        self.field2 = [aDecoder decodeObjectForKey:kField2Key];
        self.field3 = [aDecoder decodeObjectForKey:kField3Key];
        self.field4 = [aDecoder decodeObjectForKey:kField4Key];
    }
    return self;
}

- (id) copyWithZone:(NSZone *)zone
{
    FourLines *copy = [[[self class] allocWithZone:zone] init];
    field1 = [self.field1 copy];
    field2 = [self.field2 copy];
    field3 = [self.field3 copy];
    field4 = [self.field4 copy];
    
    return copy;
}

@end

#import 
#define kFilename @"archive"
#define kDataKey @"Data"

@interface PersistenceViewController : UIViewController
{
    IBOutlet UITextField *field1;
    IBOutlet UITextField *field2;
    IBOutlet UITextField *field3;
    IBOutlet UITextField *field4;
}

@property (nonatomic,retain) UITextField *field1;
@property (nonatomic,retain) UITextField *field2;
@property (nonatomic,retain) UITextField *field3;
@property (nonatomic,retain) UITextField *field4;

- (NSString *) dataFilePath;
- (void) applicationWillTerminate:(NSNotification *) notifacation;

@end

#import "ViewController.h"
#import "FourLines.h"

@implementation PersistenceViewController

@synthesize field1;
@synthesize field2;
@synthesize field3;
@synthesize field4;

- (NSString *) dataFilePath
{
    NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [path objectAtIndex:0];
    
    return [documentsDirectory stringByAppendingPathComponent:kFilename];
}

- (void) applicationWillTerminate:(NSNotification *) notifacation
{
    FourLines *fourLines = [[FourLines alloc] init];
    fourLines.field1 = field1.text;
    fourLines.field2 = field2.text;
    fourLines.field3 = field3.text;
    fourLines.field4 = field4.text;
    
    NSMutableData *data = [[NSMutableData alloc] init];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:fourLines forKey:kDataKey];
    [archiver finishEncoding];
    [data writeToFile:[self dataFilePath] atomically:YES];
    [fourLines release];
    [archiver release];
    [data release];
}

- (void) viewDidLoad
{
    NSString *filePath = [self dataFilePath];
    if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
        NSData *data = [[NSMutableData alloc] initWithContentsOfFile:[self dataFilePath]];
        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
        FourLines *fourLines = [unarchiver decodeObjectForKey:kDataKey];
        field1.text = fourLines.field1;
        field2.text = fourLines.field2;
        field3.text = fourLines.field3;
        field4.text = fourLines.field4;
        
        [unarchiver release];
        [data release];
        
    }
    
    UIApplication *app = [UIApplication sharedApplication];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillTerminate:) name:UIApplicationWillTerminateNotification object:app];
    [super viewDidLoad];
}

- (void)dealloc {
    [field1 release];
    [field2 release];
    [field3 release];
    [field4 release];
    [super dealloc];
}

@end

SQLite3

打开数据库

sqlite3 *database;

int result = sqlite3_open("/path/to/database/file",&database);

如果result等于SQLITE_OK,则表示数据库已经成功打开。SQLite3是采用可以移植的C,所有它不知道什么是NSString,所幸,,有一个NSString方法,该方法从NSString实例生成C字符串

char *cStringPath = [pathString UTF8String];

关闭数据库

sqlite3_close(database)

创建表


查询


结果集


#import 
#import "/usr/include/sqlite3.h"
#define kFilename @"data.sqlite3"

@interface PersistenceViewController : UIViewController
{
    IBOutlet UITextField *field1;
    IBOutlet UITextField *field2;
    IBOutlet UITextField *field3;
    IBOutlet UITextField *field4;
    
    sqlite3 *database;
}

@property (nonatomic,retain) UITextField *field1;
@property (nonatomic,retain) UITextField *field2;
@property (nonatomic,retain) UITextField *field3;
@property (nonatomic,retain) UITextField *field4;

- (NSString *) dataFilePath;
- (void) applicationWillTerminate:(NSNotification *) notifacation;

@end

#import "ViewController.h"
#import "FourLines.h"

@implementation PersistenceViewController

@synthesize field1;
@synthesize field2;
@synthesize field3;
@synthesize field4;

- (NSString *) dataFilePath
{
    NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [path objectAtIndex:0];
    
    return [documentsDirectory stringByAppendingPathComponent:kFilename];
}

- (void) applicationWillTerminate:(NSNotification *) notifacation
{
    for (int i=1; i<=4; i++) {
        NSString *fieldName = [[NSString alloc] initWithFormat:@"field%d",i];
        UITextField *field = [self valueForKey:fieldName];
        [fieldName release];
        NSString *update = [[NSString alloc] initWithFormat:@"insert or replace into fields(row,field_data) values (%d,'%@');",i,field.text];
        char *errorMsg;
        if (sqlite3_exec(database, [update UTF8String], NULL, NULL, &errorMsg) != SQLITE_OK) {
            NSAssert(0, @"Error updating table : %s", errorMsg);
            sqlite3_free(errorMsg);
        }
    }
    sqlite3_close(database);
}

- (void) viewDidLoad
{
    if (sqlite3_open([[self dataFilePath] UTF8String], &database) != SQLITE_OK) {
        sqlite3_close(database);
        NSAssert(0, @"");
    }
    
    char *errorMsg;
    NSString *createSQL = @"create table if not exist fields (row integer primary key,field_data text);";
    if (sqlite3_exec(database, [createSQL UTF8String], NULL, NULL, &errorMsg)!= SQLITE_OK) {
        sqlite3_close(database);
        NSAssert(0, @"");
    }
    NSString *query = @"select row,field_data from fields order by row";
    sqlite3_stmt *statement;
    if (sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil) == SQLITE_OK) {
        while (sqlite3_step(statement) == SQLITE_OK) {
            int row = sqlite3_column_int(statement, 0);
            char *rowData = (char *)sqlite3_column_text(statement, 1);
            NSString *fieldName = [[NSString alloc] initWithFormat:@"field%d",row];
            NSString *fieldValue = [[NSString alloc] initWithUTF8String:rowData];
            UITextField *field = [self valueForKey:fieldName];
            field.text = fieldValue;
            [fieldName release];
            [fieldValue release];
        }
        sqlite3_finalize(statement);
    }
}

- (void)dealloc {
    [field1 release];
    [field2 release];
    [field3 release];
    [field4 release];
    [super dealloc];
}

@end


你可能感兴趣的:(读书,iphone,sqlite,database,interface,path)