一、应用程序沙盒

IOS应用程序职能在系统为该应用所分配的文件区域下读写文件,这个文件区域就是应用程序沙盒。所有的非代码文件如:图片、声音、映象等等都存放在此。

在mac中command+shift+G命令,然后输入users/用户名/library命令进入库,然后依次进入application support/iphone simulator/版本/applications文件夹,这里面的各个文件夹对应着各个应用程序。

Documents:除了基于NSUserDefaults的首选项设置外,应用程序的数据、文件都保存在该目录下

Library:基于NSUserDefaults的首选项参数保存在Library/Preferences下

tmp:应用程序存储临时文件,ios同步时itunes不会同步这里面的数据,当应用程序不在需要这些文件时,应当删除以避免占用空间。

获取documents路径:

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *dd = [paths objectAtIndex:];

获取tmp目录:

 NSString *tempPath = NSTemporaryDirectory();

那么我们在保存数据时使用哪种发式比较好呢,这个当然还要具体情况具体对待。
当保存小数据量的数据时,可以使用NSArray或者NSDictionary,调用writeToFile:atomically:方法写入一个文件,使用时读取文件内容即可。

当保存大数据量的数据时,可以选择使用sqllite,ios提供了CoreData框架。

二、应用程序参数与用户默认设置

1、使用Settings Bundle

Settings Bundle时应用程序中的一组特殊文件,用于保存较简单的各种配置信息。如果使用了Settings Bundle,ios自带的设置应用则会显示你的app

2、使用NSUserDefaults读取、保存应用程序参数

NSUserDefaults是一个单例类,每个应用程序只有一个NSUserDefaults对象,Settings Bundle设置的参数,也可以通过NSUserDefaults来读取和设置

获取NSUserDefaults的方法:

 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

获取NSUserDefaults对象后,可以获取和设置应用程序参数

xxForKey:(NSString *) key  =>xx表示各种类型,根据key获取值

setBool:(xxx) value forKey:(NSString *) key =>设置参数

设置完参数后,调用synchronize方法进行保存。

3、属性列表

属性列表就是文章开始提到的利用NSArray和NSDictionary将数据写入到文件的保存方法。

但是有一些限制,只有下列类型的值保存到NSArray和NSDictionary中才可以直接调用writeToFile方法执行保存:

NSArray、NSMutableArray、NSDictionary、NSMutableDictionary、NSData、NSMutableData、NSString、NSMutableString、NSValue、NSNumber

如果NSArray和NSDictionary保存了我们自定义的类,那么将不能直接调用writeToFile方法执行保存。(可以考虑使用对象归档的方法进行保存)

 //使用属性列表保存3个用户的账号密码
accountList = [[NSMutableArray alloc] init];
[accountList addObject:[NSDictionary
dictionaryWithObjects:[NSArray arrayWithObjects:@"loginname",@"loginpwd", nil]
forKeys:[NSArray arrayWithObjects:@"",@"", nil]]];
[accountList addObject:[NSDictionary
dictionaryWithObjects:[NSArray arrayWithObjects:@"loginname",@"loginpwd", nil]
forKeys:[NSArray arrayWithObjects:@"",@"", nil]]];
[accountList addObject:[NSDictionary
dictionaryWithObjects:[NSArray arrayWithObjects:@"loginname",@"loginpwd", nil]
forKeys:[NSArray arrayWithObjects:@"",@"", nil]]];
[accountList writeToFile:[self filePath] atomically:YES]; //使用UIActionSheet提示用户保存成功
UIActionSheet *sheet =[[UIActionSheet alloc] initWithTitle:@"保存成功" delegate:nil cancelButtonTitle:nil destructiveButtonTitle:@"确定" otherButtonTitles:nil, nil];
[sheet showInView:self.view];

4、使用Sqlite3数据库

1)为项目增加libsqlite3.dylib,这是一个原生的C函数库

常用函数:

int sqlite3_close(sqlite3 *):关闭sqlite3 *所代表的数据连接,并释放底层数据库连接资源。在调用该函数之前,必须先调用sqlite3_finalize()函数,调用sqlite3_blob_close()函数关闭所有的blob处理器,否则将会返回SQLITE_BUSY

int sqlite3_exec(sqlite3*,const char *sql, int (*callback)(void*, int ,char**,char**),void *,char **errmsg):用于执行没有返回值的sql语句

sqlite3_int64  sqlite3_last_insert_rowid(sqlite3*):返回sqlite3代表的数据库最后一次插入行的id

int sqlite3_changes(sqlite3*):执行某条dml语句后,返回受影响行数

void sqlite3_interrupt(sqlite3*):中断一个长时间执行的查询语句

int sqlite3_complete(const char *sql):用于判断sql语句是否执行完成

int sqlite3_open(const char * filename,sqlite3 ** ppdb):打开与filename文件的链接,并让ppdb参数引用被打开的数据库连接

const char *sqlite3_sql(sqlite3_stmt *pStmt):用于提取sqlite3_stmt(预编译SQL语句产生的结果)中包装的sql语句

等等。。。太多了不一一列举了

操作sqlite数据库的大致步骤如下:

1、调用sqlite3_open方法打开与数据库的连接

2、执行语句

3、sqlite3_close函数关闭数据库连接

2)使用Core Data框架

Core Data框架是一个纯粹的面向对象的框架,允许开发者以面向对象的方式持久化操作SQLite数据库。core data底层的持久化存储方式可以是Sqlite数据库,也可以是xml,也可以是内存。

Core Data的核心概念是实体,由Core Data管理的模型对象,它必须是NSManagedObject类或者它的子类的实例。

Core Data应用中的核心API有如下几个:

托管对象模型(NSManagedObjectModel):该对象负责管理整个应用的所有实体以及实体之间的关联关系。当开发者使用Xcode的图形界面设计了实体与实体间的关联关系之后,需要使用该对象来加载、管理应用的托管对象模型

持久化存储协调器(NSPersistentStoreCoordinator):负责管理底层的存储文件,例如sqlite数据库等等

托管对象上下文(NSManagedObjectContext):该对象是Core Data的核心,增删改查都需要通过它来进行

实体描述(NSEntityDescription):关于某个实体的描述信息

抓取请求(NSFetchRequest):该对象封装了查询实体的请求,包括程序需要查询哪些实体、查询条件、排序规则等

使用Core Data持久化的步骤大致如下

1、创建NSManagedObjectModel对象来加载管理应用对应的托管对象模型

2、以NSManagedObjectModel对象为基础,根据实际需要创建NSPersistentStoreCoordinator对象,该对象确定底层数据的存储形式

3、以NSManagedObjectModel对象为基础,创建NSManagedObjectContext对象

4、对于普通的增、删、改操作,需要分别先新建实体、删除实体、修改实体,然后调用NSManagedObjectContext对象的save方法,保存修改

5、如果执行查询,需要先创建NSFetchRequest对象,在调用NSManagedObjectContext对象的executeFetchRequest:error:方法,返回所有匹配条件的实体组成的NSArray

使用Core Data的例子来和大家一起学习。

首先,创建一个创建一个Single View Application,下面有个Use Core Data选项,打上勾,之后Xcode已经为你做好了准备工作,打开AppDelete.m就可以看到

 #pragma mark - Core Data stack

 @synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator; - (NSURL *)applicationDocumentsDirectory {
// The directory the application uses to store the Core Data store file. This code uses a directory named "esitech.Unit_3" in the application's documents directory.
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
} - (NSManagedObjectModel *)managedObjectModel {
// The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
//获取实体模型文件对应的nsurl
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Unit_3" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
} - (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
// The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it.
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
} // Create the coordinator and store
//以持久化模型为基础,创建持久化存储协调器对象
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
//获取sqlite数据库文件的存储目录
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Unit_3.sqlite"];
NSError *error = nil;
NSString *failureReason = @"There was an error creating or loading the application's saved data.";
//设置存储协调器采用sqlite,如果失败打印失败信息
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
// Report any error we got.
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data";
dict[NSLocalizedFailureReasonErrorKey] = failureReason;
dict[NSUnderlyingErrorKey] = error;
error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code: userInfo:dict];
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
} return _persistentStoreCoordinator;
} - (NSManagedObjectContext *)managedObjectContext {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
if (_managedObjectContext != nil) {
return _managedObjectContext;
} NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (!coordinator) {
return nil;
}
_managedObjectContext = [[NSManagedObjectContext alloc] init];
//设置上下文使用的持久化类型
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
return _managedObjectContext;
} #pragma mark - Core Data Saving support - (void)saveContext {
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
NSError *error = nil;
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}

三个重要的对象NSManagedObjectModel、NSPersistentStoreCoordinator、NSManagedObjectContext的实例已经为你设置好了,当我们要执行相关增删改查时,直接调用委托类的managedObjectContext属性操作即可。

在创建项目后,会发现项目中有一个**.xcdatamodeld文件,点击后就会出现实体模型设计界面

 
 在刚刚的设计视图中添加一个类:EventEntity,添加两个属性=》happenDate(Data)、name(string)
单击Xcode主菜单的Editor=》Create NSManagedObject Subclass菜单,来创建一个子类,之后你的项目中就会创建一个类:EventEntity : NSManagedObject
 
先完成一些准备工作,获取appdelete对象,定义一个nameCount变量记录添加了几个对象
 #import "SqliteViewController.h"
#import "EventEntity.h"
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import "AppDelegate.h" @interface SqliteViewController ()
@property (nonatomic,weak) AppDelegate *appDelete;
@property (nonatomic) int nameCount;
@end @implementation SqliteViewController - (void)viewDidLoad {
[super viewDidLoad];
self.nameCount = ;
// Do any additional setup after loading the view.
self.appDelete = (AppDelegate *)[UIApplication sharedApplication].delegate;
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
 
5.1 添加实体
第一步:调用NSEntityDescription的 insertNewObjectForEntityForName:(NSString *) inManagedObjectContext:(NSManagedObjectContext *)方法,第一个参数为实体名,第二个参数为上下文对象
第二部:为新实体设置属性
第三部:调用NSManagedObjectContext对象的save方法保存。
 //添加操作
- (IBAction)btnAdd_Tap:(id)sender {
//创建一个新实体
EventEntity *ee = [NSEntityDescription insertNewObjectForEntityForName:@"EventEntity" inManagedObjectContext:self.appDelete.managedObjectContext];
//给实体设置属性
ee.happenDate = [NSDate date];
ee.name = [NSString stringWithFormat:@"名字%d",self.nameCount++]; //定义NSError对象接收错误信息
NSError *error;
if ([self.appDelete.managedObjectContext save:&error]) {
[[[UIAlertView alloc] initWithTitle:@"添加操作" message:[NSString stringWithFormat:@"添加成功,添加的实体的name是:%@",ee.name] delegate:nil cancelButtonTitle:@"好的" otherButtonTitles:nil, nil] show];
}else
{
NSLog(@"保存时出现错误:%@,%@",error,[error userInfo]);
}
}
 5.2 删除实体
 //删除操作
- (IBAction)btnRemove_Tap:(id)sender {
//获取要删除的实体
EventEntity *entity = [self getEntityByName:@"名字1"];
//从上下文对象中删除该实体
[self.appDelete.managedObjectContext deleteObject:entity];
NSError *error;
if (![self.appDelete.managedObjectContext save:&error]) {
NSLog(@"删除时出现错误:%@,%@",error,[error userInfo]);
}
}

5.3 修改实体

 //更新操作
- (IBAction)btnUpdate_Tap:(id)sender {
//获取要删除的实体
EventEntity *entity = [self getEntityByName:@"名字1"];
//修改实体属性
entity.happenDate = [NSDate date];
NSError *error;
if (![self.appDelete.managedObjectContext save:&error]) {
NSLog(@"删除时出现错误:%@,%@",error,[error userInfo]);
}
}

5.4 查询

 //根据名字查询一个对象
-(EventEntity *)getEntityByName:(NSString *) name
{
//创建抓取数据的请求对象
NSFetchRequest *request = [[NSFetchRequest alloc] init]; //设置要抓取哪种类型的实体
NSEntityDescription *des = [NSEntityDescription entityForName:@"EventEntity" inManagedObjectContext:self.appDelete.managedObjectContext]; //设置抓取实体
[request setEntity:des];
//定义抓取条件
NSPredicate * qcmd = [NSPredicate predicateWithFormat:@"name = %@ ",name];
[request setPredicate:qcmd]; NSError *error = nil;
//执行查询请求
NSArray *result = [[self.appDelete.managedObjectContext executeFetchRequest:request error:&error] copy];
if (error!=nil) {
NSLog(@"查询单个时出现错误:%@,%@",error,[error userInfo]);
return nil;
}
if (result.count==) {
return nil;
}
return result[];
} //获得所有实体
-(NSArray *)getAllEntities
{
//创建抓取数据的请求对象
NSFetchRequest *request = [[NSFetchRequest alloc] init]; //设置要抓取哪种类型的实体
NSEntityDescription *des = [NSEntityDescription entityForName:@"EventEntity" inManagedObjectContext:self.appDelete.managedObjectContext]; //设置抓取实体
[request setEntity:des]; NSError *error = nil;
//执行查询请求
NSArray *result = [[self.appDelete.managedObjectContext executeFetchRequest:request error:&error] copy];
//如果没有数据返回nil
if (error!=nil && result == ) {
return nil;
}
return result; }
 
 
 

IOS高级编程之二:IOS的数据存储与IO的更多相关文章

  1. iOS高级编程之XML,JSON数据解析

    解析的基本概念 所谓“解析”:从事先规定好的格式串中提取数据 解析的前提:提前约定好格式.数据提供方按照格式提供数据.数据获取方按照格式获取数据 iOS开发常见的解析:XML解析.JSON解析 一.X ...

  2. [深入浅出Cocoa]iOS网络编程之Socket

    http://blog.csdn.net/kesalin/article/details/8798039 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[+]   [深入浅出Co ...

  3. iOS多线程编程之NSThread的使用

      目录(?)[-] 简介 iOS有三种多线程编程的技术分别是 三种方式的有缺点介绍 NSThread的使用 NSThread 有两种直接创建方式 参数的意义 PS不显式创建线程的方法 下载图片的例子 ...

  4. iOS多线程编程之NSThread的使用(转)

    本文由http://blog.csdn.net/totogo2010/原创 1.简介: 1.1 iOS有三种多线程编程的技术,分别是: 1..NSThread 2.Cocoa NSOperation  ...

  5. [转] iOS多线程编程之Grand Central Dispatch(GCD)介绍和使用

    介绍: Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其他的对称多处理系统的系统.这建立在任务并行执行的线程池模式的基础上的.它首 ...

  6. [转]iOS多线程编程之NSThread的使用

    1.简介: 1.1 iOS有三种多线程编程的技术,分别是: 1..NSThread 2.Cocoa NSOperation (iOS多线程编程之NSOperation和NSOperationQueue ...

  7. iOS 多线程编程之Grand Central Dispatch(GCD)

    介绍: Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其它的对称多处理系统的系统.这建立在任务并行运行的线程池模式的基础上的. 它 ...

  8. iOS多线程编程之NSThread的使用(转载)

    1.简介: 1.1 iOS有三种多线程编程的技术,分别是: 1.NSThread 2.Cocoa NSOperation (iOS多线程编程之NSOperation和NSOperationQueue的 ...

  9. [转] iOS多线程编程之NSOperation和NSOperationQueue的使用

    <iOS多线程编程之NSThread的使用> 介绍三种多线程编程和NSThread的使用,这篇介绍NSOperation的使用. 使用 NSOperation的方式有两种, 一种是用定义好 ...

随机推荐

  1. Android 代码混淆、第三方平台加固加密、渠道分发 完整教程(图文)

    第一步:代码混淆(注意引入的第三方jar) 在新版本的ADT创建项目时,混码的文件不再是proguard.cfg,而是project.properties和proguard-project.txt. ...

  2. 小数量宽带用户的福音,Panabit 云计费easyradius 接口隆重发布,PA宽带计费系统

    PA接口在早前就发布了,但是一直迟迟没有发布官方说明文档,由于最近问的客户较多,特写了这篇文档 由于PA使用标准radius认证协议,所以用户需要在本地搭建一个计费,由于大部分用户的数量只有几百个,不 ...

  3. adding validation annotators to model classes 在linq to EntityFrame的Model中添加前台验证validation annotators

    The same solution can be applied for LINQ to SQL. The snippet the article shows for using the Metada ...

  4. [原创]Android Handler使用Message的一个注意事项

    最近发现了一个莫名其妙的问题,在使用Handler.post(Runnable)这个接口时,Runnable有时候没有运行,非常奇怪,后来发现是因为调用Handler.removeMessage()时 ...

  5. C# Json帮助类

    using System; using System.Collections.Generic; using System.Web; using System.Text; using System.Re ...

  6. Oracle数据库入门——高水位线详解

    一.什么是水线(High Water Mark)? 所有的oracle段(segments,在此,为了理解方便,建议把segment作为表的一个同义词) 都有一个在段内容纳数据的上限,我们把这个上限称 ...

  7. fdisk命令使用说明

    CentOS我新建了几个分区,比如/dev/sda4,sda5我想挂在一个目录下,用mount  /dev/sda5  /disk ,总提示mount:you must specify the fil ...

  8. Go目录

    1. Go语言获取项目当前路径 2. Go语言TCP/UDP Socket编程 3. Go语言实现HashSet

  9. new/delete和malloc/free的区别

    通俗易懂版本:http://zhidao.baidu.com/question/86185100 1 new/delete和malloc/free最大区别是对对象的理解. 如果你使用 Foo* foo ...

  10. linux中mysql密码找回的两种方式

    方法一:修改my.cnf配置文件 1.首先确认服务器出于安全的状态,也就是没有人能够任意地连接MySQL数据库. 因为在重新设置MySQL的root密码的期间,MySQL数据库完全出于没有密码保护的  ...