NSUserDefaults *userD = [NSUserDefaults
standardUserDefaults];
//
把一个object保存到本地
[userD setObject:@"xiaochao"
forKey:@"name"];
// 把修改同步到本地文件
[userD synchronize];
//
从本地取出object
NSLog(@"%@", [userD
objectForKey:@"name"]);
//
从本地移除
[userD removeObjectForKey:@"name"];
// 判断用户是不是第一次使用程序
if ([userD
objectForKey:@"first"] ==
nil) {
NSLog(@"第一次使用");
[userD setObject:@"suibian"
forKey:@"first"];
} else {
NSLog(@"不是第一次");
}
当然还有好多方法, 就不一一提到:如: [userD setBool:<#(BOOL)#> forKey:<#(NSString *)#>];
三、 SQLite
首先,我们要知道,SQLite是以C语言为基础编写的,所以市面上很多公司的老板更喜欢让员工去使用SQLite去编写数据库,因为他们不懂iOS出的CoreData编写的数据库。并且C语言是底层语言,这就使得SQLite变得尤为重要。强烈建议你去下载:MesaSQLite,
它是打开数据库的工具,也可以让你更好的理解SQLite输入的语句为什么这么写。
//
代码编写如下:我们需要先建立这样一个类,把相应的代码封装进去,方便我们日后长期使用
// Movie是之间建好的一个类,我们存储对象一般都是对某个类进行存储, 很容易理解下面分别封装了打开数据库,关闭你数据库,增、删、改、查四个主要功能,同时还包括一个往数据库中添加的时候,数据后中是否已经包了这个对象(如收藏功能,加入收藏过,就没必要再添加一次收藏)
// 在.h中的代码如下
#import
<Foundation/Foundation.h>
#import <sqlite3.h>
@class Movie;
@interface DBCenter :
NSObject
{
sqlite3 *dbPoint;
}
+ (DBCenter *)shareInstance;
- (BOOL)openDB;
- (BOOL)closeDB;
- (BOOL)createMovieTabel;
- (BOOL)insertMovie:(Movie *)movie;
- (NSMutableArray *)selectAllMovies;
- (BOOL)isContainMovie:(Movie *)movie;
@end
// 在.m中的代码如下
#import
"DBCenter.h"
#import "Movie.h"
@implementation DBCenter
// 单例方法
+ (DBCenter *)shareInstance
{
static
DBCenter *center =
nil; // static静态,程序运行期间center值不变
static
dispatch_once_t onceToken; // 代码块, 程序只运行一次
dispatch_once(&onceToken, ^{
center = [[DBCenter
alloc] init];
[center
openDB]; // 因为我们第一次使用的时候,需要先打开数据库,创建表,所以直接写在这里更加方便
[center
createMovieTabel]; // 创建的表
});
return center;
}
// 打开数据库
- (BOOL)openDB
{
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES)
lastObject];
NSString *dbPath = [docPath
stringByAppendingPathComponent:@"DoubanMovie.db"];
NSLog(@"%@", dbPath);
int result =
sqlite3_open([dbPath
UTF8String], &dbPoint);
NSLog(@"打开数据库的结果:
%d", result);
return [self
judgeResult:result
type:@"打开数据库"];
}
// 关闭数据库
- (BOOL)closeDB
{
int result =
sqlite3_close(dbPoint);
return [self
judgeResult:result
type:@"关闭数据库"];
}
// 用于判断我操作成功与否, 并打印出来
- (BOOL)judgeResult:(int)result type:(NSString *)type
{
if (result ==
SQLITE_OK) {
NSLog(@"%@成功",
type);
return
YES;
}
else {
NSLog(@"%@失败,
失败编号: %d", type, result);
return NO;
}
}
// 创建表
- (BOOL)createMovieTabel
{
NSString *sqlStr =
@"create table movie (movieId interger primary key, title text)";
return [self
helperWithSqlStr:sqlStr type:@"创建表"]; // 因为每次改变的只是SQLite语句,所以只需向方法中传递一个语句即可
}
// 插入对象
- (BOOL)insertMovie:(Movie *)movie
{
NSString *sqlStr = [NSString
stringWithFormat:@"insert into movie values(%@, '%@')", movie.movieId, movie.title];
return [self
helperWithSqlStr:sqlStr
type:@"添加一条数据"]; //
同上
}
//
查找
- (NSMutableArray *)selectAllMovies
{
//
查询所有的学生数据
NSString *sqlStr =
@"select * from movie";
sqlite3_stmt *stmt =
nil;
int result = sqlite3_prepare(dbPoint, [sqlStr
UTF8String], -1, &stmt,
NULL);
//
建立一个空数组, 用来装学生数据
NSMutableArray *movieArr = [NSMutableArray
array];
if (result == SQLITE_OK) {
//
遍历结果中的所有数据
while (sqlite3_step(stmt) ==
SQLITE_ROW) {
//
每一条数据都对应一个student对象
Movie *movie = [[Movie
alloc] init];
movie.movieId = [NSString
stringWithFormat:@"%d",
sqlite3_column_int(stmt,
0)];
movie.title = [NSString
stringWithUTF8String:(const
char *)sqlite3_column_text(stmt,
1)];
[movieArr
addObject:movie];
[movie
release];
}
}
// 回收状态指针的内存,
将sql的改变结果保存到数据库.
sqlite3_finalize(stmt);
//
将数组返回
return movieArr;
}
// 插入对象
- (BOOL)isContainMovie:(Movie *)movie
{
NSString *sqlStr = [NSString
stringWithFormat:@"select * from movie where movieId = %@", movie.movieId];
sqlite3_stmt *stmt =
nil;
int result =
sqlite3_prepare(dbPoint, [sqlStr
UTF8String], -1, &stmt,
NULL);
// 建立一个空数组,
用来装学生数据
if (result == SQLITE_OK) {
//
遍历结果中的所有数据
while (sqlite3_step(stmt) ==
SQLITE_ROW) {
sqlite3_finalize(stmt);
return YES;
}
}
sqlite3_finalize(stmt);
return
NO;
}
//
封装的方法,方便给数据库传递命令
- (BOOL)helperWithSqlStr:(NSString *)sqlStr type:(NSString
*)type
{
int result =
sqlite3_exec(dbPoint, [sqlStr
UTF8String], NULL,
NULL, NULL);
return [self
judgeResult:result
type:type];
}
@end
四、 CoreData
我很难用代码和注释给你讲明白, 所以我把思路和代码以及其实现的原理图提供给你, 具体的含义还需要你去研究。
这是iOS出的高级数据库,可以这么说,相对于SQLite来说,CoreData无论从安全角度,或者可持续性方面,都领先于SQLite。只不过,好多非iOS的开发人员看不懂它而已。最简单的一个例子,数据库升级,如果使用SQLite来做的话,就会变得非常繁琐。而CoreData却把它变得如此轻松。
首先,它的实现由很多种,你可以在创建的时候直接勾选CoreData,也可以把CoreData的代码封装成一个类,那么下次你想用的时候,即使你没有勾选CoreData也可以很容易的用CoreData去创建数据库。下面,让我们去封装一个CoreData方法的类吧!
1. 建立一个模型DataModle
取名:“High_coreDataClass05”
2. 封装一个类(Student是我之间建的一个类)
//
.h里面
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@interface CoreDataManager :
NSObject
// 数据管理器
@property (readonly,
strong, nonatomic)
NSManagedObjectContext *managedObjectContext;
// 数据模型器
@property (readonly,
strong, nonatomic)
NSManagedObjectModel *managedObjectModel;
// 连接器
@property (readonly,
strong, nonatomic)
NSPersistentStoreCoordinator *persistentStoreCoordinator;
// 单例方法
+ (CoreDataManager *)defaultManager;
// 保存
- (void)saveContext;
// 获取本地存储路径
- (NSURL *)applicationDocumentsDirectory;
@end
// .m里面
@implementation CoreDataManager
// 单例方法
+ (CoreDataManager *)defaultManager
{
static
CoreDataManager *manager =
nil;
//
只运行一次的线程
static
dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[CoreDataManager
alloc] init];
});
return manager;
}
#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 "com.lanou3g.High_coreDataClass05" 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 *modelURL = [[NSBundle
mainBundle] URLForResource:@"High_coreDataClass05"
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]];
NSURL *storeURL = [[self
applicationDocumentsDirectory]
URLByAppendingPathComponent:@"High_coreDataClass05.sqlite"];
NSError *error =
nil;
NSString *failureReason =
@"There was an error creating or loading the application's saved data.";
//
允许自动桥接存储设置
NSDictionary *option = [NSDictionary
dictionaryWithObject:@(YES)
forKey:NSMigratePersistentStoresAutomaticallyOption];
if (![_persistentStoreCoordinator
addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeURL options:option
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:9999
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();
}
}
}
@end
3. 视图控制器里面调用
#import "ViewController.h"
#import "CoreDataManager.h"
#import "Student.h"
@interface
ViewController ()
@property (nonatomic,
strong) CoreDataManager *manager;
@property (nonatomic,
strong) NSArray *resultArr;
@end
@implementation ViewController
- (void)viewDidLoad {
[super
viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//
通过单例方法获取本地存储管理对象
self.manager = [CoreDataManager
defaultManager];
//
打印本地存储的路径
NSLog(@"url: %@", [self.manager
applicationDocumentsDirectory]);
}
// 增加
- (IBAction)add:(id)sender {
//
写法1
// 创建实体描述对象
// 参数1:
实体名称 (注意首字母大写)
// 参数2:
在哪个数据管理器下读取
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:self.manager.managedObjectContext];
// 创建数据对象
// 参数1:
实体描述对象 (通过该对象对数据对象进行初始化)
// 参数2:
插入到哪个数据管理器 (交给谁去管理)
Student *stu = [[Student alloc] initWithEntity:entity insertIntoManagedObjectContext:self.manager.managedObjectContext];
//
写法2
Student *stu = [NSEntityDescription
insertNewObjectForEntityForName:@"Student"
inManagedObjectContext:self.manager.managedObjectContext];
stu.name =
@"xiaochao";
//
快速创建一个NSNumber类型的对象,
用@
stu.age =
@24;
stu.sex =
@"n";
//
保存操作
[self.manager
saveContext];
}
- (IBAction)select:(id)sender {
//
写法1
// 创建一个获取请求
// 参数:
实体名称
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Student"];
// 谓词 (只有对和错两种结果)
//request.predicate = [NSPredicate predicateWithFormat:@"name = 'xiaochao'"];
// 谓词 (只有对和错两种结果)
多条件查找
//request.predicate = [NSPredicate predicateWithFormat:@"name = 'xiaochao' OR age = 100"];
//request.predicate = [NSPredicate predicateWithFormat:@"name = 'xiaochao' OR age = 100"];
//request.predicate = [NSPredicate predicateWithFormat:@"name CONTAINS 'xiao'"];
// 向数据管理器发送获取数据的请求
//NSArray *resultArr = [self.manager.managedObjectContext executeFetchRequest:request error:nil];
//for (Student *stu in resultArr) {
//NSLog(@"name: %@, age: %@", stu.name, stu.age);
//}
//
写法2 (直接打fe会出现一个代码块,
然后选fetch - Core - Data)
NSFetchRequest *fetchRequest = [[NSFetchRequest
alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"Student"
inManagedObjectContext:self.manager.managedObjectContext];
[fetchRequest
setEntity:entity];
// Specify criteria for filtering which objects to fetch
NSPredicate *predicate = [NSPredicate
predicateWithFormat:@"name CONTAINS 'xiao'"];
[fetchRequest
setPredicate:predicate];
// Specify how the fetched objects should be sorted
//
参数1: 按照某个键去排序
//
参数2: 是否升序
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor
alloc]
initWithKey:@"age"
ascending:YES];
[fetchRequest
setSortDescriptors:[NSArray
arrayWithObjects:sortDescriptor,
nil]];
NSError *error = nil;
self.resultArr = [self.manager.managedObjectContext
executeFetchRequest:fetchRequest
error:&error];
if (self.resultArr ==
nil) {
NSLog(@"error: %@", error);
}
//
遍历数组
for (Student *stu
in self.resultArr) {
NSLog(@"name: %@, age: %@", stu.name, stu.age);
}
}
- (IBAction)change:(id)sender {
for (Student *stu
in self.resultArr) {
stu.name =
@"xuying";
stu.age =
@23;
stu.sex =
@"n";
}
[self.manager
saveContext];
}
- (IBAction)delete:(id)sender {
for (Student *stu
in self.resultArr) {
[self.manager.managedObjectContext
deleteObject:stu];
}
[self.manager
saveContext];
}
这就是整个的流程,希望对你有所帮助!