首页 > 代码库 > iOS数据存储的几种方式
iOS数据存储的几种方式
iOS的数据存储是iOS应用开发的重要知识点:
关于这方面知识,网上有很多介绍,但对于代码层次的使用方式并未有系统全面介绍。此文章针对iOS稍熟悉的童鞋,需要对CoreData的原理有一定的了解。目前存储方式大概有以下几种:
- NSKeyedArchiver 适用简单数据加密
- NSUserDefaults 适用配置参数
- Write 文件操作,同NSKeyedArchiver
- SQLite3 操作较复杂,不建议使用。
- CoreData 取代SQLite3,但要遵循NSManagedObjectContext基本规则。
UT代码确保使用方式正确。请阅读以下内容:
#import <XCTest/XCTest.h> #import <sqlite3.h> #import "CoreDataHelper.h" @interface StudyUITests : XCTestCase @end @implementation StudyUITests - (void)setUp { [super setUp]; } - (void)tearDown { [super tearDown]; } -(void)testCoreData{ CoreDataHelper *coreHelper = [[CoreDataHelper alloc] init]; [coreHelper coreDataTest]; } -(void)testSqlite3{ sqlite3 *db; NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; NSString *databasePath = [documentPath stringByAppendingPathComponent:@"test.sqlite"]; NSLog(@"db path: %@",databasePath); if(sqlite3_open([databasePath UTF8String], &db) != SQLITE_OK){ sqlite3_close(db); NSLog(@"open sqlite fail!"); NSAssert(FALSE, @"create sqlite error"); } NSString *sqlCreateTable = @"CREATE TABLE IF NOT EXISTS ptable (ID INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER, address TEXT)"; char *error; if(sqlite3_exec(db, [sqlCreateTable UTF8String], NULL, NULL, &error) != SQLITE_OK){ sqlite3_close(db); NSLog(@"can not create table."); NSAssert(FALSE, @"create table error"); } NSString *deleteAllSql = @"delete from ptable"; if(sqlite3_exec(db, [deleteAllSql UTF8String], NULL, NULL, &error) != SQLITE_OK){ sqlite3_close(db); NSLog(@"delete values from table"); NSAssert(FALSE, @"delete values from table"); } NSString *sql1 = [NSString stringWithFormat: @"INSERT INTO '%@' ('%@', '%@', '%@') VALUES ('%@', '%@', '%@')", @"ptable", @"name", @"age", @"address", @"first name", @"23", @"pukou"]; NSString *sql2 = [NSString stringWithFormat: @"INSERT INTO '%@' ('%@', '%@', '%@') VALUES ('%@', '%@', '%@')", @"ptable", @"name", @"age", @"address",@"second name", @"20", @"qixia"]; if(sqlite3_exec(db, [sql1 UTF8String], NULL, NULL, &error) != SQLITE_OK){ sqlite3_close(db); NSLog(@"can not insert sql1"); NSAssert(FALSE, @"create insert db (sql1) error"); } if(sqlite3_exec(db, [sql2 UTF8String], NULL, NULL, &error) != SQLITE_OK){ sqlite3_close(db); NSLog(@"can not insert sql2"); NSAssert(FALSE, @"create insert db (sql2) error"); } //Read data and check result. NSString *query = @"select * from ptable"; sqlite3_stmt *statement; if(sqlite3_prepare_v2(db, [query UTF8String], -1, &statement, nil) == SQLITE_OK){ //start to traverse data int size = 0; while (sqlite3_step(statement) == SQLITE_ROW) { size++; char *name = (char*)sqlite3_column_text(statement, 1); int age= (int)sqlite3_column_int(statement, 2); char *address = (char*)sqlite3_column_text(statement, 3); NSString *nameStr = [[NSString alloc] initWithUTF8String:name]; NSString *addressStr = [[NSString alloc] initWithUTF8String:address]; NSLog(@"name: %@ age: %d address: %@",nameStr,age,addressStr); } NSAssert(size == 2, @"size should 2"); }else{ NSAssert(FALSE, @"query db error"); } sqlite3_close(db); } -(void)testWriteToFile{ NSString *st1 = @"first"; NSString *st2 = @"second"; NSArray *array = [NSArray arrayWithObjects:st1,st2, nil]; NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSAssert(path != nil, @"path is nil"); NSString *filename = [path stringByAppendingPathComponent:@"test.data"]; NSAssert([array writeToFile:filename atomically:YES],@"write successfully"); NSMutableArray *savearray = [NSMutableArray arrayWithContentsOfFile:filename]; NSAssert([[savearray objectAtIndex:0] isEqualToString:st1], @"not equal to str1"); NSAssert([[savearray objectAtIndex:1] isEqualToString:st2], @"not equal to str2"); } -(void)testUserDefault{ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *name = @"test"; [defaults setObject:name forKey:@"name"]; UIImage *image = [UIImage imageNamed:@"photo"]; NSData *imageData = UIImagePNGRepresentation(image); [defaults setObject:imageData forKey:@"image"]; //now read from data NSString *name1= [defaults objectForKey:@"name"]; NSData *imageData1 = [defaults objectForKey:@"image"]; NSAssert([name1 isEqualToString:name], @"name1 is equal to test"); NSAssert([imageData1 isEqualToData:imageData], @"image data is not equal"); } -(void)testKeyedArchiver{ NSString *save1 =@"test1"; NSString *save2 =@"test2"; NSArray *array = [NSArray arrayWithObjects:save1, save2, nil]; NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSString *filename = [path stringByAppendingPathComponent:@"savedatatest"]; NSLog(@"filename : %@",filename); //save data NSAssert([NSKeyedArchiver archiveRootObject:array toFile:filename],@"archive successfully."); array = [NSKeyedUnarchiver unarchiveObjectWithFile:filename]; save1 = [array objectAtIndex:0]; NSAssert([save1 isEqualToString:@"test1"], @"save1 must equals to test1"); save2 = [array objectAtIndex:1]; NSAssert([save2 isEqualToString:@"test2"], @"save1 must equals to test2"); } @end
CoreData的使用稍微复杂一些,所以将其单独放入Helper类中。Entity model包含name,age 和 address 三个属性。可在测试工程创建,并生成Entity对象。
#import "CoreDataHelper.h" #import <CoreData/CoreData.h> #import "Entity.h" @interface CoreDataHelper() @property (strong, nonatomic) NSManagedObjectModel *managedObjectModel; @property (strong, nonatomic) NSManagedObjectContext *managedObjectContext; @property (strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; -(NSPersistentStoreCoordinator *)persistentStoreCoordinator; -(NSManagedObjectContext *)managedObjectContext; -(NSManagedObjectModel *)managedObjectModel; @end @implementation CoreDataHelper -(void)coreDataTest{ NSError *error = nil; NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Entity" inManagedObjectContext:self.managedObjectContext]; NSFetchRequest *request = [[NSFetchRequest alloc] init]; [request setEntity:entityDescription]; NSArray *oldResult = [[self.managedObjectContext executeFetchRequest:request error:&error] mutableCopy]; for (Entity *bb in oldResult) { [self.managedObjectContext deleteObject:bb]; } NSAssert([self.managedObjectContext save:&error], @"deleting....."); /******insert *****/ Entity *entity = [[Entity alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:nil]; entity.name = @"test"; entity.age = [NSNumber numberWithInt:20]; entity.address = @"beijing"; [self.managedObjectContext insertObject:entity]; NSAssert([self.managedObjectContext save:&error], @"inserting....."); /*****query *****/ NSSortDescriptor *sortDescription = [[NSSortDescriptor alloc] initWithKey:@"age" ascending:NO]; NSArray *sortDescriptions = [[NSArray alloc] initWithObjects:sortDescription, nil]; [request setSortDescriptors:sortDescriptions]; NSMutableArray *array = [[self.managedObjectContext executeFetchRequest:request error:&error] mutableCopy]; for (Entity *bb in array) { NSLog(@"name: %@ age:%@ address:%@",bb.name,bb.age,bb.address); } NSAssert([array count] == 1, @"count size is equal to 1"); /***** update and check****/ NSArray *updateResult = [[self.managedObjectContext executeFetchRequest:request error:&error] mutableCopy]; Entity *first = [updateResult objectAtIndex:0]; first.name = @"one"; NSAssert([self.managedObjectContext save:&error], @"updating....."); updateResult = [[self.managedObjectContext executeFetchRequest:request error:&error] mutableCopy]; first = [updateResult objectAtIndex:0]; NSAssert([first.name isEqualToString:@"one"], @"need to equeal one"); /**** insert and check ****/ entity = [[Entity alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:nil]; entity.name = @"test2"; entity.age = [NSNumber numberWithInt:23]; entity.address = @"nanjing"; [self.managedObjectContext insertObject:entity]; NSAssert([self.managedObjectContext save:&error], @"inserting....."); array = [[self.managedObjectContext executeFetchRequest:request error:&error] mutableCopy]; for (Entity *bb in array) { NSLog(@"name: %@ age:%@ address:%@",bb.name,bb.age,bb.address); } NSAssert([array count] == 2, @"now size is equal to 2"); } -(NSPersistentStoreCoordinator *)persistentStoreCoordinator{ if(_persistentStoreCoordinator) return _persistentStoreCoordinator; NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSURL *storeURL = [NSURL fileURLWithPath:[documentPath stringByAppendingPathComponent:@"person.sqlite"]]; NSError *error = nil; _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; if(![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]){ NSLog(@"persistent error : %@",[error userInfo]); } return _persistentStoreCoordinator; } -(NSManagedObjectContext *)managedObjectContext{ if(_managedObjectContext) return _managedObjectContext; NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if(coordinator){ _managedObjectContext = [[NSManagedObjectContext alloc] init]; [_managedObjectContext setPersistentStoreCoordinator:coordinator]; } return _managedObjectContext; } -(NSManagedObjectModel *)managedObjectModel{ if(_managedObjectModel) return _managedObjectModel; NSURL *modeUrl = [[NSBundle mainBundle] URLForResource:@"Entity" withExtension:@"momd"]; _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modeUrl]; return _managedObjectModel; } @end
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。